近来一向在忙公司炒股大赛的页面,终究在昨天把他给上线了。一个看似简朴的页面,做起来才晓得个中的艰苦,潜伏深坑。由于直接运用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.items
的scrollLeft
值,让全部ul转动起来。规划上须要注重的有以下几点:
超越容器的部份须要隐蔽,注重,此处的隐蔽是给
ul.items
的,注重与float: left
规划的差异。.items { overflow: hidden; }
ul.items
的内容不能折行,因而.items { white-space: nowrap; }
须要适配到挪动端,因而
li.item
的宽度就必然会跟着设配宽度的变小而变小。@media (max-width: 780px) { .item { width: 190px; } } @media (max-width: 580px) { .item { width: 160px; } }
- html规划中的
<!-- -->
是为了消弭display: inline-block
元素之间带来的间隙。
那末无缝转动的障眼法究竟是什么呢?本来用图片形貌会越发直观一点,不过这里我想偷个懒,用笔墨给人人报告一下,愿望人人能看懂。
我们有子元素123456, 一个一个向左转动,复制一份,就变成123456123456
。假如我们在团体挪动到第二个1的时刻,将团体的位置拉回到第一个1来,也就是初始位置,由于有div.items
的overflow: 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/…