手机版

原生JS实现移动web轮播的详细说明(结合Tween算法做轮子)

时间:2021-09-03 来源:互联网 编辑:宝哥软件园 浏览:

相信大家都应该知道,移动端的轮播是我们共同的需求,最快的实现方式就是使用第三方代码,比如swiper。然而,当我们遇到一些复杂的转盘需求时,我们往往束手无策,不知道如何改变。

所以要尽量自己造一些轮子,适应各种复杂多变的需求;另一方面,如果你自己的代码中有bug,很容易修复,这将大大提高你自己。

没有阅读swiper源代码,我试图自己实现一个简单实用的移动转盘。经过几个小时的思考和实践,我终于实现了(如图):

在移动端实现轮播比pc复杂,主要表现在以下几个方面:

1.转盘应适应不同宽度/dpr的屏幕

2.需要使用触摸相关事件

3.不同的型号支持不同的触摸事件,可能存在一些兼容性问题

4.手指移动图片的一部分,剩余的距离需要自动完成

5.自动距离完成需要缓和时间曲线

但是编程解决问题的想法是相似的,

当我们使用旋转木马地图时,我们可以仔细观察它,并通过现象:看到本质

当我们使用旋转木马地图时,我们可以仔细观察它。通过现象可以看出,指的本质是放在画面上,手指向左或向右移动,画面随之移动;手指移动的距离小时,画面自动恢复位置;当手指移动很远的距离时,它会自动切换到下一个;当手指快速向左或向右移动时,会切换到下一个;图片转盘是无限循环。我们需要以3 1 2 3 1的方式实现,也就是N ^ 2张图片,实现N张图片的无限循环轮播。通过分析这一现象,我们可以提出一个基本的实现方案:

1.手指触摸事件可以通过三个事件来实现:触摸开始触摸移动触摸

2.手指触摸开始时,我们需要记录手指的X坐标,可以使用触摸的pageX属性;这个时间点,

3.当触摸移动手指时,我们还需要记录pageX并记录累计移动距离moveX

4.当手指离开时,记录时间点,根据前两步计算的X方向移动的距离,以及时间点之间的差值

5.通过比较X方向的移动距离和是否应该切换到下一张图片来确定移动方向;根据时间判断用户是否进行了左右扫动操作

6.使用translate3d可以实现运动图像,并且开启了硬件加速

7.移动一段距离需要缓和效果。我们可以在Tween算法中使用easeOut来实现我们每次移动的距离;当然,您也可以使用js来制作过渡动画

实现源代码(仅供参考):

头型

head meta charset=' utf-8 ' meta name=' viewport ' content=' width=device-width,initial-scale=.5,maximum-scale=. 5 ' title mobile carousel/title style * { box-sizing : border-box;margin : 0;padding: 0 }。横幅{ overflow:隐藏;宽度: 100%;高度: 300px }。班纳。img-wrap { position:相对;height: 100% }。banner img { display:块;绝对位置:top : 0;宽度: 100%;高度: 100% }/样式/头部html结构

div class=' Banner ' div class=' img-wrap ' id=' imgWrap ' img src=' http : images/Banner _ 3 . jpg ' data-index='-1 ' img src=' http : images/Banner _ 1 . jpg ' data-index=' 0 ' img src=' http : images/Banner _ 2 . jpg ' data-index=' 1 ' img src=' http : images/Banner _ 3 . jpg。

给你,htmlelement。原型。tweenranslatexamate是扩展到所有HTML元素类的tweenranslatexamate方法

移动一段距离,我们需要使用计时器来帮助我们完成这个重复的操作

脚本htmlelement。原型。twentranslatexanimate=函数(开始、结束、回调){ var duration=50 var t=0;var vv=结束-开始;var Tween={ quad : { ease out : }函数(t,b,c,d){ return-c *(t/=d)*(t-2)b;} } };这个。timer=setInterval(function(){ var dis=start Tween .Quad.easeOut(t,0,vv,持续时间);这个。风格。transform=' translate 3d(' dis ' px,0,0)';if(vv 0 parseInt(这。风格。转变。切片(12))=end){ this。风格。transform=' translate 3d '(ParSeint(dis)' px,0,0 ');clearInterval(这个。计时器);回调回调();} if(vv 0 parseInt(这。风格。转变。切片(12))=end){ this。风格。transform=' translate 3d '(ParSeint(dis)' px,0,0 ');clearInterval(这个。计时器);回调回调();} }.绑定(本),4);}/脚本触摸事件部分

script ~ function(){ var lastPX=0;//上一次触摸的位置x坐标,需要计算出手指每次移动的一点点距离var movex=0;//记录手指移动的x方向值var imgWrap=文档。getelementbyid(' IMgwrap ');var startX=0;//开始触摸时手指所在x坐标var ENDx=0;//触摸结束时手指所在的x坐标位置var imgSize=imgwrap。孩子们。长度-2;//图片个数var t1=0;//记录开始触摸的时刻var T2=0;//记录结束触摸的时刻可变宽度=window.innerWidth//当前窗口宽度var nodeList=文档。query selectorall(# IMgwrap img’);//所有轮播图节点数组NodeList //给图片设置合适的左边的值,注意querySelectorAll返回节点列表,具有为每一个方法nodeList.forEach(函数(节点,索引){ node。风格。left=(index-1)*宽度' px ';});/** * 移动图片到当前的tIndex索引所在位置* @param {number} tIndex要显示的图片的索引* */函数对索引(tIndex){ var dis=-(tIndex * width);var start=parsent(IMgwrap。风格。转变。切片(12));//动画移动imgwrap。twentranslatexanimate(start,dis,function(){ setTimeout(function(){ movex=dis;if(Tindex===IMgSize){ IMgRap。风格。transform=' translate 3d(0,0,0)';movex=0;} if(Tindex===-1){ IMgwrap。风格。transform=' translate 3d(' width *(1-IMgsize)' px,0,0 ');movex=-width *(IMgsize-1);} }, 0);});} /** * 处理各种触摸事件,包括touchstart、touchend、touchmove、touchcancel * @param {Event} evt回调函数中系统传回的射流研究…事件对象* */函数触摸(evt){ var touch=evt。target Touch[0];var tar=evt . target var index=ParSeint(tar。GetAttribute(' data-index ');if(evt。type==' touch move '){ var di=ParSeint(touch。PageX-LastPx);endX=touch.pageXmovex=diimgwrap。风格。webkittransform=' translate 3d(' movex ' px,0,0)';lastPX=touch . pagex } if(evt . type===' touch end '){ var减=ENDx-startX;t2=新日期()。getTime()-t1;if (Math.abs(减)0) { //有拖动操作if (Math.abs(减)宽* 0.4 t2 500) { //拖动距离不够,返回!toIndex(索引);} else { //超过一半,看方向console.log(减);if (Math.abs(减)20) { console.log('距离很短减);toIndex(索引);返回;}如果(减0) { //endX startX,向左滑动,是下一张到index(index 1)} else {//ENDx startX,向右滑动,是上一张toIndex(index - 1) } } } else { //没有拖动操作} } if(evt。type===' touch start '){ LastPx=touch。PageXstartX=lastPXendX=startXt1=新日期()。getTime();}返回false} imgwrap。addeventlistener(' touch start ',touch,false);imgwrap。addeventlistener(' touch move ',touch,false);imgwrap。addeventlistener(' touch end ',touch,false);imgwrap。addeventlistener(' touch cancel ',touch,false);}();/script在触摸事件中最关键的参数是页面x参数,记录x的位置。

当然这只是一个演示,还需要进一步的优化和封装,以便于我们用在真实的项目。

这个演示只是提供了一个解决问题的思路。有了这个想法,我相信各种复杂的需求也可以得到解决.

本文采用Tween算法来实现缓和效果,也可以使用transtion动画来实现,代码更加简洁。请参考转盘图://www . JB 51 . net/article/123304 . htm的优化。

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:原生JS实现移动web轮播的详细说明(结合Tween算法做轮子)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。