在做移动端开发的时候,必不可少的是轮播图,下面这篇文章主要给大家介绍了关于利用纯JS实现移动端web轮播图的相关资料,重要的是结合Tween算法造轮子,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
前言
相信大家应该都知道,移动端的轮播图是我们比较常见的需求, 我们最快的实现方式往往是 使用第三方的代码, 例如 swiper , 但当遇到一些比较复杂的轮播图需求时, 往往是束手无策,不知道怎么改.
所以我们要尝试去自己造一些轮子, 以适应各种复杂多变的需求; 另外一点, 自己写的代码如果有bug是很容易修复的, 对自身的提高也很大.
在没有阅读swiper源码的过程下,我尝试自己实现一个简易而不失实用的移动端轮播图, 经过几个小时的思考和实践终于还是实现了(如图):
实现移动端的轮播图要比pc复杂一些,主要表现在以下几个方面:
1.轮播图要适应不同宽度/dpr的屏幕
2.需要使用 touch相关的事件
3.不同机型对 touch事件支持的不太一样,可能会有一些兼容性问题
4.手指移动图片一部分距离,剩下的距离需要自动完成
5.自动完成距离需要有 ease 时间曲线
但编程解决问题的思路都是差不多的,
我们在使用轮播图的时候可以仔细观察,通过现象看到本质:
我们在使用轮播图的时候可以仔细观察,通过现象看到本质:
手指放在图片上, 手指向左或者向右移动, 图片也随之移动;
手指移动的距离少时,图片自动复原位置;手指移动的距离多时,自动切换到下一张;
手指向左或者向右移动的快时,会切换到下一张;
图片轮播是无限循环的, 我们需要采用 3 1 2 3 1的方式来实现, 即 N+2张图来实现N张图的无限循环轮播
我们通过分析现象,可以提出一个基本实现方案:
1. 手指触摸事件可以通过 touchstart touchmove touchend 3个事件来实现
2.在手指 touchstart的时候我们需要记录 手指的x坐标, 可以使用 touch的pageX属性; 还有 这个时间点,
3.手指touchmove的时候我们也需要记录pageX,并且记录累计移动的距离 moveX
4.手指离开的时候,记录时间点, 根据前两步计算的 x方向移动的距离,时间点之差
5.通过比较x方向移动距离来判断移动方向, 以及是否应该切换到下一张图; 根据时间判断用户是否进行了左右扫动的操作
6.移动图片可以使用 translate3d来实现,开启硬件加速
7.移动一段距离需要 easeOut效果,我们可以使用 Tween算法中的easeOut来实现我们每次移动的距离; 当然也可以使用 js设置 transition动画
实现源码(仅供参考):
head头部样式
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5"> <title>移动端轮播图</title> <style> * { box-sizing: border-box; margin: 0; padding: 0 } .banner { overflow: hidden; width: 100%; height: 300px } .banner .img-wrap { position: relative; height: 100% } .banner img { display: block; position: absolute; top: 0; width: 100%; height: 100% } </style> </head>
HTML结构
<p class="banner"> <p class="img-wrap" id="imgWrap"> <img src="images/banner_3.jpg" data-index="-1"> <img src="images/banner_1.jpg" data-index="0"> <img src="images/banner_2.jpg" data-index="1"> <img src="images/banner_3.jpg" data-index="2"> <img src="images/banner_1.jpg" data-index="3"> </p> </p>
JS代码1, easeOut动画式移动,
这里的 HTMLElement.prototype.tweenTranslateXAnimate ,是给所有的HTML元素类扩展的tweenTranslateXAnimate方法
移动一段距离我们需要使用定时器来帮助我们完成,这个重复的操作
<script> HTMLElement.prototype.tweenTranslateXAnimate = function (start, end, callback) { var duration = 50; var t = 0; var vv = end - start; var Tween = { Quad: { easeOut: function (t, b, c, d) { return -c * (t /= d) * (t - 2) + b; } } }; this.timer = setInterval(function () { var dis = start + Tween.Quad.easeOut(++t, 0, vv, duration); this.style.transform = 'translate3d(' + dis + 'px, 0, 0)'; if (vv > 0 && parseInt(this.style.transform.slice(12)) >= end) { this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; clearInterval(this.timer); callback && callback(); } if (vv < 0 && parseInt(this.style.transform.slice(12)) <= end) { this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; clearInterval(this.timer); callback && callback(); } }.bind(this), 4); } </script>
touch事件部分
<script> ~function () { var lastPX = 0; // 上一次触摸的位置x坐标, 需要计算出手指每次移动的一点点距离 var movex = 0; // 记录手指move的x方向值 var imgWrap = document.getElementById('imgWrap'); var startX = 0; // 开始触摸时手指所在x坐标 var endX = 0; // 触摸结束时手指所在的x坐标位置 var imgSize = imgWrap.children.length - 2; // 图片个数 var t1 = 0; // 记录开始触摸的时刻 var t2 = 0; // 记录结束触摸的时刻 var width = window.innerWidth; // 当前窗口宽度 var nodeList = document.querySelectorAll('#imgWrap img'); // 所有轮播图节点数组 NodeList // 给图片设置合适的left值, 注意 querySelectorAll返回 NodeList, 具有 forEach方法 nodeList.forEach(function (node, index) { node.style.left = (index - 1) * width + 'px'; }); /** * 移动图片到当前的 tIndex索引所在位置 * @param {number} tIndex 要显示的图片的索引 * */ function toIndex(tIndex) { var dis = -(tIndex * width); var start = parseInt(imgWrap.style.transform.slice(12)); // 动画移动 imgWrap.tweenTranslateXAnimate(start, dis, function () { setTimeout(function () { movex = dis; if (tIndex === imgSize) { imgWrap.style.transform = 'translate3d(0, 0, 0)'; movex = 0; } if (tIndex === -1) { imgWrap.style.transform = 'translate3d(' + width * (1 - imgSize) + 'px, 0, 0)'; movex = -width * (imgSize - 1); } }, 0); }); } /** * 处理各种触摸事件 ,包括 touchstart, touchend, touchmove, touchcancel * @param {Event} evt 回调函数中系统传回的 js 事件对象 * */ function touch(evt) { var touch = evt.targetTouches[0]; var tar = evt.target; var index = parseInt(tar.getAttribute('data-index')); if (evt.type === 'touchmove') { var di = parseInt(touch.pageX - lastPX); endX = touch.pageX; movex += di; imgWrap.style.webkitTransform = 'translate3d(' + movex + 'px, 0, 0)'; lastPX = touch.pageX; } if (evt.type === 'touchend') { var minus = endX - startX; t2 = new Date().getTime() - t1; if (Math.abs(minus) > 0) { // 有拖动操作 if (Math.abs(minus) < width * 0.4 && t2 > 500) { // 拖动距离不够,返回! toIndex(index); } else { // 超过一半,看方向 console.log(minus); if (Math.abs(minus) < 20) { console.log('距离很短' + minus); toIndex(index); return; } if (minus < 0) { // endX < startX,向左滑动,是下一张 toIndex(index + 1) } else { // endX > startX ,向右滑动, 是上一张 toIndex(index - 1) } } } else { //没有拖动操作 } } if (evt.type === 'touchstart') { lastPX = touch.pageX; startX = lastPX; endX = startX; t1 = new Date().getTime(); } return false; } imgWrap.addEventListener('touchstart', touch, false); imgWrap.addEventListener('touchmove', touch, false); imgWrap.addEventListener('touchend', touch, false); imgWrap.addEventListener('touchcancel', touch, false); }(); </script>
在触摸事件中最关键的参数是 pageX参数, 记录x的位置.
当然这只是一个demo,还需要进一步的优化和封装, 以便于我们用在真实的项目.
本demo仅仅是提供了一个解决问题的思路, 有了这个思路,相信各种复杂的需求也得以解决...
以上是详解如何使用原生JS实现移动端web轮播图效果的详细内容。更多信息请关注PHP中文网其他相关文章!

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Atom编辑器mac版下载
最流行的的开源编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6
视觉化网页开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),