还在为无缝转动而懊恼?是时刻完全get到这个学问点了

近来一向在忙公司炒股大赛的页面,终究在昨天把他给上线了。一个看似简朴的页面,做起来才晓得个中的艰苦,潜伏深坑。由于直接运用jquery来写页面逻辑,因而要比设想中庞杂许多。无论是从规划,功用照样逻辑上来讲,都有值得总结的处所。

这篇文章重要说说关于无缝转动的完成。

刚开始进修js的时刻,至心以为无缝转动是一个奇异的功用。背地究竟是怎么回事?为何明显只要几个方块就是滚不到头?厥后邃晓了道理以后,发明原来是经由过程一些障眼法来完成。

道理

假如须要无缝转动的4个元素是一个ul.items中的6个li.item。我们将掌握ul.items在容器.wrap中转动。html代码以下:

ul.items示意className为items的ul元素,其他处所同理

<div class="wrap">
    <ul class="items"><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner0.8a07a886.jpg" alt=""></li><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner1.56bcecb3.png" alt=""></li><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner2.9a7e8842.jpg" alt=""></li><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner3.47acdfbd.png" alt=""></li><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner5.e9205d49.jpg" alt=""></li><!--
    --><li class="item"><img src="https://static.tigerbrokers.com/portal/images/cooperation/stockGame/v2-partner6.83b14a71.png" alt=""></li><!--
    --></ul>
</div>

我们的目的是完成程度方向上的转动,因而须要li.item程度分列。能够到达目的的体式格局经常使用的有运用float: left,或许运用display: inline-block。我们晓得掌握页面元素的挪动不过就是掌握元素的left, top, translateX, translateY,另有一种就是掌握转动间隔scrollTop, scrollLeft。规划的挑选,同时也会影响到js掌握属性的挑选。

本例挑选运用display: inline-block规划,并掌握ul.itemsscrollLeft值,让全部ul转动起来。规划上须要注重的有以下几点:

  1. 超越容器的部份须要隐蔽,注重,此处的隐蔽是给ul.items的,注重与float: left规划的差异。

    .items { overflow: hidden; }
  2. ul.items的内容不能折行,因而

    .items { white-space: nowrap; }
  3. 须要适配到挪动端,因而li.item的宽度就必然会跟着设配宽度的变小而变小。

    @media (max-width: 780px) {
        .item {
            width: 190px;
        }
    }
    
    @media (max-width: 580px) {
        .item {
            width: 160px;
        }
    }
  4. html规划中的<!-- -->是为了消弭display: inline-block元素之间带来的间隙。

那末无缝转动的障眼法究竟是什么呢?本来用图片形貌会越发直观一点,不过这里我想偷个懒,用笔墨给人人报告一下,愿望人人能看懂。

我们有子元素123456, 一个一个向左转动,复制一份,就变成123456123456。假如我们在团体挪动到第二个1的时刻,将团体的位置拉回到第一个1来,也就是初始位置,由于有div.itemsoverflow: hidden在,中心发作的变化我们没办法用肉眼辨认出来,就觉得是一向在向左挪动,永久都停不下来。

表达能力有限,假如没懂再连系代码明白一下吧,或许留言给我

功用完成

一说到活动,我们经常想到的要领多是应用setTimeout或许setInterval, 不过呢,html5为我们供应了一个越发高性能的要领requestAnimationFrame

在性能上,requestAnimationFrame > setTimeout > setInterval。详细缘由人人能够找找相干的材料相识一下。而setTimeout的最小定时价为100/60,因而,我们在完成活动时,从性能与兼容性两方面斟酌,经常会以下声明:

var lastTime = 0,
    nextFrame = window.requestAnimationFrame       ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.msRequestAnimationFrame     ||
                function(callback) {
                    var currTime = + new Date,
                        delay = Math.max(1000/60, 1000/60 - (currTime - lastTime));
                    lastTime = currTime + delay;
                    return setTimeout(callback, delay);
                },
    cancelFrame = window.cancelAnimationFrame               ||
                  window.webkitCancelAnimationFrame         ||
                  window.webkitCancelRequestAnimationFrame  ||
                  window.mozCancelRequestAnimationFrame     ||
                  window.msCancelRequestAnimationFrame      ||
                  clearTimeout;

我们须要晓得转动到什么位置回退到0,这个位置恰好就是复制之前一切子元素加一同的总长度。然则子元素的宽度会由于装备宽度的转变而转变,因而合营规划,我们须要作以下处置惩罚:

// 单个子元素的宽度
var itemW = 240;
if ($items.children().eq(0).width() == 190) {
    itemW = 190;
}
if ($items.children().eq(0).width() == 160) {
    itemW = 160;
}

// 目的位置
var target = itemW * $items.children().length;

为了完成障眼法,须要复制一分子元素

$items.html( $items.html() + $items.html() );

定义一个活动函数,这里的活动为匀速活动,因而比较简朴,只须要一向+1即可。假如须要活动快一点,就多加一点

var timer = null;

function adAni() {
    timer = nextFrame(function() {
        scrollX += 1;

        // 当递增到大于了目的间隔,就直接变成0
        if (scrollX >= target) {
            scrollX = 0;
        }
        $items.scrollLeft(scrollX);
        adAni();
    });
}

// 运转这个函数就能够完成无缝转动啦。
adAni();

如许无缝转动就已完成了。不过另有一些其他的需求。比方,鼠标mouseover时,须要住手转动,脱离以后又要重新启动转动。由于需求的变化,在挪动端还须要能够滑动items.ul,手指松开以后继承转动。因而我们须要一个辨别pc于挪动端的函数。经由过程UA的不同来辨别。

function isMobile() {
    return /(iphone|ipad|ipod|ios|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|Webos|symbian|windows phone)/i.test(navigator.userAgent);
}

在pc端,鼠标移入时住手,鼠标移除时继承转动

if (!isMobile()) {
    $items.on('mouseover', function() {
        cancelFrame(timer);
    }).on('mouseout', function() { adAni(); });
}

在挪动端,能够摆布滑动,滑动时住手自动转动,松开以后继承自动转动。挪动端的滑动事宜,重要经由过程touchstart, touchmove, touchend来完成,与pc端的mousedown, mousemove, mouseup相似。

var sX, sL;
$items.on('touchstart', function(e) {
    cancelFrame(timer);
    sX = e.originalEvent.changedTouches[0].pageX;
    sL = $items.scrollLeft();
}).on('touchmove', function(e) {
    var dis = e.originalEvent.changedTouches[0].pageX - sX;
    var nowX = sL - dis;
    if (nowX > target) {
        nowX = 0;
    }
    $items.scrollLeft(nowX);
}).on('touchend', function(e) {
    scrollX = $items.scrollLeft();
    if (scrollX >= target) {
        scrollX = 0;
    }
    adAni();
})

那末到这里,就已基础搞定啦。虽然是一个比较简朴的小例子,然则个中也包含了一些经常使用的功用,比方运用requestAnimationFrame来完成活动,挪动端的滑动事宜等。在这里总结一下分享给人人,有疑问迎接讨论。

实例地点:
http://codepen.io/yangbo5207/…

《还在为无缝转动而懊恼?是时刻完全get到这个学问点了》

    原文作者:九死蚕传人bo
    原文地址: https://segmentfault.com/a/1190000005138317
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞