• 巧用JS数组的slice方法进行循环排序,仿学步园文章推荐滚动效果


    1. 仿站效果

    今天看到学步园网站右边有个文章推荐的滚动栏目,觉得挺有意思,效果如下:

    2. 原理猜想

    如此小动画的效果,首先想到的可能是一个长数据列表,不断变化列表的长度,利用外部边框的遮罩裁剪效果,从而做出就像是文章标题在滚动的效果。

    原理如下:

    图中,黑色边框代表显示区域,灰色边框代表 ul>li 列表项目 ,Time1~Time3 分别代表不同时刻的列表项运行高度。

     双倍内容的列表项目整体上移动,利用显示区域的遮罩效果,达到一种标题在轮番切换的错觉。

    至于为什么要双倍内容?是因为在运动到底部内容的时候,不会因为内容都在上方,而出现空白。

    查看源代码发现,基本和上面的猜想一致。

     1 <div id="scat">
     2                 <ul>
     3             <li><a href="https://www.xuebuyuan.com/2201282.html" rel="bookmark" title="详细阅读作业的提交和监控(二)">作业的提交和监控(二)</a></li>
     4         </ul>
     5                 <ul>
     6             <li><a href="https://www.xuebuyuan.com/2201280.html" rel="bookmark" title="详细阅读作业的提交和监控(一)">作业的提交和监控(一)</a></li>
     7         </ul>
     8                 <ul>
     9             <li><a href="https://www.xuebuyuan.com/2198273.html" rel="bookmark" title="详细阅读Boost – Function 分析">Boost – Function 分析</a></li>
    10         </ul>
    11                 <ul>
    12             <li><a href="https://www.xuebuyuan.com/2198272.html" rel="bookmark" title="详细阅读奇技淫巧 – C/C++ 宏自身迭代">奇技淫巧 – C/C++ 宏自身</a></li>
    13         </ul>
    14                 <ul>
    15             <li><a href="https://www.xuebuyuan.com/2198221.html" rel="bookmark" title="详细阅读模板的 SFINAE 原则">模板的 SFINAE 原则</a></li>
    16         </ul>
    17                 <ul>
    18             <li><a href="https://www.xuebuyuan.com/2198220.html" rel="bookmark" title="详细阅读Octopress 和 Git 的结合">Octopress 和 Git 的结合</a></li>
    19         </ul>
    20                 <ul>
    21             <li><a href="https://www.xuebuyuan.com/2198208.html" rel="bookmark" title="详细阅读Electric-fence 介绍">Electric-fence 介绍</a></li>
    22         </ul>
    23                 <ul>
    24             <li><a href="https://www.xuebuyuan.com/2198206.html" rel="bookmark" title="详细阅读原子操作浅谈">原子操作浅谈</a></li>
    25         </ul>
    26             
    27                 <ul>
    28             <li><a href="https://www.xuebuyuan.com/2201282.html" rel="bookmark" title="详细阅读作业的提交和监控(二)">作业的提交和监控(二)</a></li>
    29         </ul>
    30                 <ul>
    31             <li><a href="https://www.xuebuyuan.com/2201280.html" rel="bookmark" title="详细阅读作业的提交和监控(一)">作业的提交和监控(一)</a></li>
    32         </ul>
    33                 <ul>
    34             <li><a href="https://www.xuebuyuan.com/2198273.html" rel="bookmark" title="详细阅读Boost – Function 分析">Boost – Function 分析</a></li>
    35         </ul>
    36                 <ul>
    37             <li><a href="https://www.xuebuyuan.com/2198272.html" rel="bookmark" title="详细阅读奇技淫巧 – C/C++ 宏自身迭代">奇技淫巧 – C/C++ 宏自身</a></li>
    38         </ul>
    39                 <ul>
    40             <li><a href="https://www.xuebuyuan.com/2198221.html" rel="bookmark" title="详细阅读模板的 SFINAE 原则">模板的 SFINAE 原则</a></li>
    41         </ul>
    42                 <ul>
    43             <li><a href="https://www.xuebuyuan.com/2198220.html" rel="bookmark" title="详细阅读Octopress 和 Git 的结合">Octopress 和 Git 的结合</a></li>
    44         </ul>
    45                 <ul>
    46             <li><a href="https://www.xuebuyuan.com/2198208.html" rel="bookmark" title="详细阅读Electric-fence 介绍">Electric-fence 介绍</a></li>
    47         </ul>
    48                 <ul>
    49             <li><a href="https://www.xuebuyuan.com/2198206.html" rel="bookmark" title="详细阅读原子操作浅谈">原子操作浅谈</a></li>
    50         </ul>
    51             </div>
    学步园代码

    3. 实现优化

    但是,列表项目多写一倍,难免有些累赘,代码也不干净。

    有没有其他的实现方式呢?

    既然是动画,我们都知道,动画都是借助人眼的视觉暂留效果来实现的,如果只是人为的改变title的标题排序,是不是同样实现同样的效果呢(类比小人书的,每张图都是有一点点差异,在翻阅的速度变快的时候,好像小人书里的人物真的在跑起来。)

    因此,在设计列表的时候,只是写一倍的列表项,然后通过编程实现列表的排序算法。

    说到这个算法,也很简单,借助于数组存放 li 列表中的内容,然后定时改变数组的值,然后渲染列表就实现了列表项的排序。

    举例:

    对于数组  a = [1,2,3,4,5,6] ; 我们希望数组运动起来,依次就要实现:

    a = [1,2,3,4,5,6]; // time1
    
    a = [2,3,4,5,6,1]; // time2
    
    a = [3,4,5,6,1,2]; // time3
    
    a = [4,5,6,1,2,3]; // time4
    
    a = [5,6,1,2,3,4]; // time5
    
    a = [6,1,2,3,4,5]; // time6
    
    a = [1,2,3,4,5,6]; // time7 (循环)

    如此改变值,数组就好像动起来了。

    但是,人工实现的话是很容易,但是如何封装成函数,让它自动适应数组条数。

    考虑数组Array有slice方法,用于数组的切割。原型如下:

    // slice 原型
    arr.slice([begin[, end]])
    
    // slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。
    // 原始数组不会被改变。

    因此,如下函数可以实现数组的动态变化:

    /**
     * 数组循环
     * param:arr Array 待变化数组
     * return:变化后的数组
     */
    function change(arr)
    {
      return a.slice(1).concat(a.slice(0,1));
    }

    于是,仿写功能代码(引入jQuery):

     1     <ul>
     2             <li><a href="https://www.xuebuyuan.com/2201282.html" rel="bookmark" title="详细阅读作业的提交和监控(二)">1 作业的提交和监控(二)</a></li>
     3             <li><a href="https://www.xuebuyuan.com/2201280.html" rel="bookmark" title="详细阅读作业的提交和监控(一)">2 作业的提交和监控(一)</a></li>
     4             <li><a href="https://www.xuebuyuan.com/2198273.html" rel="bookmark" title="详细阅读Boost – Function 分析">3 Boost – Function 分析</a></li>
     5             <li><a href="https://www.xuebuyuan.com/2198272.html" rel="bookmark" title="详细阅读奇技淫巧 – C/C++ 宏自身迭代">4 奇技淫巧 – C/C++ 宏自身</a></li>
     6             <li><a href="https://www.xuebuyuan.com/2198221.html" rel="bookmark" title="详细阅读模板的 SFINAE 原则">5 模板的 SFINAE 原则</a></li>
     7             <li><a href="https://www.xuebuyuan.com/2198220.html" rel="bookmark" title="详细阅读Octopress 和 Git 的结合">6 Octopress 和 Git 的结合</a></li>
     8             <li><a href="https://www.xuebuyuan.com/2198208.html" rel="bookmark" title="详细阅读Electric-fence 介绍">7 Electric-fence 介绍</a></li>
     9             <li><a href="https://www.xuebuyuan.com/2198206.html" rel="bookmark" title="详细阅读原子操作浅谈">8 原子操作浅谈</a></li>
    10 </ul>
     1 $(function(){
     2     
     3   var arr = [];
     4   
     5   $('a').each(function(){
     6     arr.push($(this).text())
     7     
     8   });
     9   
    10   //console.log(arr);
    11   
    12   
    13   var t = setTimeout(function(){
    14     
    15     rr();
    16     
        // 延时处理函数(递归) 17 function rr() 18 { 19 arr = cc(arr); 20 $.each(arr,function(index,element){ 21 $('a').eq(index).html(arr[index]) 22 }); 23 t = setTimeout(function(){ 24 rr(); 25 },1000) 26 // clearTimeout(t); 27 } 28 },1000) 29 30 31 function cc(a) 32 { 33 return a.slice(1).concat(a.slice(0,1)); 34 } 35 36 37 38 });

    效果如下:

    4. 总结

    1. 动画的实现原理是利用视觉暂留效应,与实现方式无关。

    2. 数组的浅拷贝方法 Slice(start,[end])  ,所谓浅拷贝,也是不改变数组原值。 

    参考文献

    1. 仿造学步园效果

    2. Array.prototype.slice() - JavaScript | MDN

  • 相关阅读:
    VUE Class动态绑定
    SPA 单页面
    pdf.js使用记录
    vue 采坑 pdfjsdist/es5/build/pdf.js
    搜索引擎搜索技巧
    Service Broker初创建
    SQL Server 2008 R2 SP1升级到SQL Server 2012后的注意事项
    怎么都无法解决的 "Cannot Generate SSPI Context"
    Service Broker 应用示例
    接口测试工具 Jmeter使用笔记(一:编写一个http请求)
  • 原文地址:https://www.cnblogs.com/yqmcu/p/11753608.html
Copyright © 2020-2023  润新知