前言

相信大家应该都知道,移动端的轮播图是我们比较常见的需求, 我们最快的实现方式往往是 使用第三方的代码, 例如 swiper , 但当遇到一些比较复杂的轮播图需求时, 往往是束手无策,不知道怎么改.
所以我们要尝试去自己造一些轮子, 以适应各种复杂多变的需求; 另外一点, 自己写的代码如果有bug是很容易修复的, 对自身的提高也很大.
在没有阅读swiper源码的过程下,我尝试自己实现一个简易而不失实用的移动端轮播图, 经过几个小时的思考和实践终于还是实现了(如图):
实现移动端的轮播图要比pc复杂一些,主要表现在以下几个方面:
1.轮播图要适应不同宽度/dpr的屏幕
2.需要使用 touch相关的事件
3.不同机型对 touch事件支持的不太一样,可能会有一些兼容性问题
4.手指移动图片一部分距离,剩下的距离需要自动完成
5.自动完成距离需要有 ease 时间曲线
但编程解决问题的思路都是差不多的,
我们在使用轮播图的时候可以仔细观察,通过现象看到本质:
我们通过分析现象,可以提出一个基本实现方案:
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结构
<div class="banner"> <div 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"> </div> </div>
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仅仅是提供了一个解决问题的思路, 有了这个思路,相信各种复杂的需求也得以解决...
本文中使用的 tween算法来实现 ease-out效果 ,也可以使用 transtion动画实现, 代码更加简洁,参见轮播图优化篇: https://www./article/123304.htm
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
# js移动端轮播图
# 原生js移动端图片轮播
# 原生js移动端轮播图
# 移动web开发之touch事件实例详解
# javascript移动设备Web开发中对touch事件的封装实例
# webpack的移动端适配方案小结
# vue项目在webpack2实现移动端字体自适配功能
# Vue2.0+Vux搭建一个完整的移动webApp项目的示例
# 移动web开发技能之touch事件详解
# 来实现
# 可以使用
# 拖动
# 切换到
# 下一张
# 解决问题
# 自动完成
# 都是
# 是一个
# 放在
# 不太
# 有一定
# 很容易
# 少时
# 可以通过
# 仅仅是
# 这只
# 要比
# 束手无策
# 如图
相关文章:
合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?
七夕网站制作视频,七夕大促活动怎么报名?
建站之星后台密码遗忘如何找回?
seo网站制作优化,网站SEO优化步骤有哪些?
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
,如何利用word制作宣传手册?
网站制作新手教程,新手建设一个网站需要注意些什么?
宁波免费建站如何选择可靠模板与平台?
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
建站之星云端配置指南:模板选择与SEO优化一键生成
如何在阿里云香港服务器快速搭建网站?
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
建站之星安装路径如何正确选择及配置?
Bpmn 2.0的XML文件怎么画流程图
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
如何快速生成橙子建站落地页链接?
建站之星价格显示格式升级,你的预算足够吗?
如何用wdcp快速搭建高效网站?
网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何获取免费开源的自助建站系统源码?
如何快速启动建站代理加盟业务?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
如何构建满足综合性能需求的优质建站方案?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
宝华建站服务条款解析:五站合一功能与SEO优化设置指南
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
实惠建站价格推荐:2025年高性价比自助建站套餐解析
黑客如何利用漏洞与弱口令入侵网站服务器?
高防服务器:AI智能防御DDoS攻击与数据安全保障
IOS倒计时设置UIButton标题title的抖动问题
相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?
家庭建站与云服务器建站,如何选择更优?
网站微信制作软件,如何制作微信链接?
购物网站制作公司有哪些,哪个购物网站比较好?
网站制作难吗安全吗,做一个网站需要多久时间?
如何高效利用亚马逊云主机搭建企业网站?
如何快速辨别茅台真假?关键步骤解析
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】
javascript中对象的定义、使用以及对象和原型链操作小结
学校建站服务器如何选型才能满足性能需求?
如何选择高性价比服务器搭建个人网站?
动图在线制作网站有哪些,滑动动图图集怎么做?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
建站之星后台密码如何安全设置与找回?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
建站VPS选购需注意哪些关键参数?
*请认真填写需求信息,我们会在24小时内与您取得联系。