自制 移动端 纯原生 Slider滑动插件
在Google搜关键字“slider”或“swiper”能找到一大堆相关插件,自己造轮子是为了能更好的理解其中的原理。
给这个插件取名为“veSlider”是指“very easy slider”非常简单的一个滑动插件。
这只是个半成品,仅仅实现了手指滑动、自动轮播、跳转等基本功能。代码撑死了200行不到,用的原理也比较简单粗暴。
点击跳转到Github上代码地址。扫描下面的二维码可以查看在线demo:
一、实现原理与效果
1)在下图中,将“ul”容器设置为相对定位,子标签“li”设置为绝对定位
2)移动的效果,其实就是动态修改translateX的值
3)相邻的两张图片能够贴在一起,就是translateX起的作用
4)动态给“li”添加或移除过渡效果,可以实现缓动
5)当你向左滑动最后一张图片,跟着出来的是第一张;或者当你向右滑动第一张图片,跟着出来的是最后一张图片
6)在第5点中,要实现这种效果需要做些控制,注意“li”标签最后会被设置为visibility,就是在做相关的控制,后面会讲到
7)根据下图可以看到,当前的“li”的translateX值肯定是0,然后上一张为-320px,下一张320px
二、结构
1)CSS
只是做了简单通用设置,可以自定义扩充。
1 .veSlider { 2 position: relative; 3 list-style: none; 4 margin: 0; 5 padding: 0; 6 width: 100%; 7 overflow: hidden; 8 } 9 .veSlider > li { 10 position: absolute; 11 top: 0; 12 left: 0; 13 list-style: none; 14 overflow: hidden; 15 height: inherit; 16 }
2)HTML
为了实现方便,我直接将相关的ul与li标签写死在页面中。
高级点的话,可以通过JS脚本动态输出,并且在输出的时候可以做图片预加载等处理。
height写在了style中,因为各种情况下的高度是不同的,所以自定义设置
1 <ul class="veSlider" style="height:180px" id="veSlider"> 2 <li> 3 <a href="http://www.cnblogs.com/strick/"> 4 <img src="img/banner.jpg" width="100%" /> 5 </a> 6 </li> 7 </ul>
3)JavaScript
通过new一个veSlider对象做初始化。
var slider = new veSlider({container: document.getElementById('veSlider') });
目前可以传入的参数只有4个。容器container目前只支持单个的,例如上面的“getElementById”;不支持列表初始化,例如“getElementsByTagName”等
var defaults = {container: '', //容器对象auto: false, //自动轮播easing: 'ease-in', //缓动类型duration: 3000 //自动轮播间隔时间 };
三、实现代码
1)插件封装
现在有比较时髦的AMD、UMD模块规范,为了让插件支持这些规范,需要做一些声明。
为了防止在引入其他JS脚本的时候,将window或undefined重写掉,会传入原生的window与undefined。
;(function(factory) {/* CommonJS module. */if (typeof module === "object" && typeof module.exports === "object") {module.exports = factory(window);/* AMD module. */} else if (typeof define === "function" && define.amd) {define(factory(window));/* Browser globals. */} else {factory(window);} }(function(global, undefined) {"use strict";}));
2)构造函数
1. 默认参数与传入的参数做合并
2. 一些值的初始化,例如容器container、偏移对象offset
3. 容器尺寸的获取,通过方法“getBoundingClientRect”获得。关于尺寸获取可以参考《JavaScript中尺寸、坐标》
4. 给容器绑定事件,“touchstart”、“touchmove”等。事件绑定用到了“handleEvent”方式绑定。事件方面的资料可以参考《JavaScript中事件处理》
5. 获取容器中的子集,并将这些子集的translateX值初始化
6. 初始化自动轮播。下面是部分代码:
function veSlider(opts) {this.opts = extend(opts, defaults);//默认参数与传入参数合并this.size = this.container.getBoundingClientRect(); //容器尺寸this.children = slice.call(this.container.children); //容器的子集this.currentIndex = 0; //当前索引this._bind(); //绑定动画事件this.caculate(this.currentIndex); //初始化子集的偏移量this.opts.auto && this.play(); //初始化自动轮播 };
3)切换子集的判断
在“touchend”事件中,做了简单的判断。
1. 对于慢速滑动,如果滑动的距离超过了当前容器的一半,那就做切换操作
2. 间隔时间在 300ms 内就算快速滑动,滑动距离只要超过 14,就做切换操作
3. 下图第一次是慢速,第二次是快速
4)slideTo方法控制某个子集滑动到指定位置
veSliderProtytype.slideTo = function(index, time) {this.currentIndex = index = this._setThreshold(index);var other = this.direction == CONST.LEFT ? (index - 1) : (index + 1);other = this._setThreshold(other);//隐藏需要移动的子集this.children.forEach(function(dom, i) {if (i == index || i == other) {return;}dom.style.visibility = 'hidden';});//手指移动的时候用.1 自动移动的时候用.4this.caculate(index, time || '.1'); };
1. 传入当前的子集索引,然后根据_setThreshold方法获取到正确的索引值
2. _setThreshold控制“<0”的数设置为0,“>last”也就是最大索引值的数,设置为last
3. 给other值赋值,根据缓存的direction方向,判断贴在一起的子集是上一个还是下一个,同样也要做_setThreshold判断
4. 隐藏会移动的图片,这个代码就是用来解决上面“实现原理与效果”中第6点提到的问题
5. 下图是演示如果不隐藏会出现的问题,滑动的时候出现了最后那张图片
5. 最后做位移计算
5)caculate方法计算偏移值
veSliderProtytype.caculate = function(index, time, offsetX) {var _this = this, last = this.last;this.children.forEach(function(dom, i) {var x = i - index;if (index == 0 && i == last) {x = -1;} else if (index == last && i == 0) {x = 1;}setTransition(dom, _this.opts.easing, time);setTranslateX(dom, x, _this.size, offsetX || 0);}); };
1. 计算相对当前子集的尺寸偏移倍数,通过“i - index”取得值
2. 再判断当前子集是第一个或最后一个,这两个位置比较特殊
3. 设置过渡与translateX的相关值
4. 偏移值是通过计算的“offsetX + size.width * i”,容器宽度的倍数加上当前移动的距离
5. 以容器宽度为320px为例,通过上面的计算,可以让当前子集translateX为0,前一张为-320px,后一张为320px,再后一张就是两倍640px
四、可以改进的部分
1、CSS可以有更多的效果,也可以嵌入到JavaScript中
2、li标签可以用JS脚本输出,而不用写死在页面中
3、支持数组初始化,例如container设置为通过“getElementsByTagName”获取到的数组
4、支持更多的自定义参数设置,目前只有4个
5、浏览器兼容性,目前只支持webkit内核相关的
6、在各个事件里,可以有自己定义的事件
7、目前只支持左右滑动,上下滑动的话要做些更灵活的修改
还有很多方面可以改进,这里就不列举了。
本文转自 咖啡机(K.F.J) 博客园博客,原文链接:http://www.cnblogs.com/strick/p/5297491.html,如需转载请自行联系原作者
自制 移动端 纯原生 Slider滑动插件相关推荐
- react 原生html 插件,纯原生JS的瀑布流插件Macy.js,前端必备插件
这是一款非常轻量级的纯原生JS的瀑布流插件--Macy.js,如今图片和视频网站非常多,非常适应瀑布流这样的布局方式来呈现给用户. 所以,选择一款简单易用的瀑布流js插件,可以让前端工程师快速开发出漂 ...
- 原生JS实现移动端模块的左右滑动切换效果,基于vue、stylus
原生JS实现移动端模块的左右滑动动画效果,基于vue.stylus 大概实现方案: 手指touch屏幕的整个过程,会派发touchstart.touchmove.touchend三个事件,对这三个事件 ...
- Swiper(Swiper master)是目前应用较广泛的移动端网页触摸内容滑动js插件
为什么80%的码农都做不了架构师?>>> Swiper(Swiper master)是目前应用较广泛的移动端网页触摸内容滑动js插件 http://www.swiper.com ...
- html5 原生插件,前端必备插件之纯原生JS的瀑布流插件Macy.js
这是一款非常轻量级的纯原生JS的瀑布流插件--Macy.js,如今图片和视频网站非常多,非常适应瀑布流这样的布局方式来呈现给用户. 这款流布局JS插件仅有4KB的大小,可以说是非常轻量级的哦.配置也比 ...
- html手机页面选项卡,移动端网页纯原生js选项卡tab切换
适合移动网页纯原生js选项卡tab切换 *{ margin: 0; padding: 0} ul,li{ list-style: none} .tabClick{ background: #f3f3f ...
- 利用notepad++的正则表达式提取所有匹配的单词(纯原生不用插件)
利用notepad++的正则表达式提取所有匹配的单词(纯原生不用插件) 怎么就使用notepad++原生功能就实现提取所有api呢? 工作中需要把出过事情的和已经分析过的api接口都进行数据格式化再梳 ...
- 纯原生组件化-模块化的探索
纯原生的组件化.模块化的一次小小的尝试,用到了如下几个新特性: shadown-DOM 对HTML标签结构的一个封装,真正意义上的组件,能保证 shadow-DOM 中的DOM元素不会被外界影响,内部 ...
- 快速入门在Vue中使用滑动插件Swiper
前言 swiper 开源.免费.强大的滑动插件. swiper中文网 https://www.swiper.com.cn/ Swiper4中文API https://www.swiper.com.cn ...
- H5网页App和纯原生的App差距在哪?
1.动画 动画有很多种,比如侧边栏菜单的滑入滑出.元素的响应动画.页面切换之间的过场等等,在H5之下的众多实现方法都没有办法达到纯原生的性能.一般这些的话有几种不同的选择:css3动画.javasc ...
最新文章
- mysql中的索引对查询的影响
- 一个系统的base.css,兼容IE7,IE8,IE9,IE10,IE11,firefox,safari,谷歌,360,世界之窗等浏览器起的公共css
- jMeter 打开项目时遇到错误消息 CannotResolveClassException: com.blazemeter.jmeter.RandomCSVDataSetConfig
- 网络15软工个人作业5——软件工程总结
- java学习(4):第一个java程序
- MySql 缓存查询原理与缓存监控 和 索引监控
- python管理系统web版_Python学生管理系统(web网页版)-Go语言中文社区
- catti二级笔译综合能力真题_CATTI 二级口笔译教材、真题和模拟试题汇总!
- 不恢复余数除法原理_《有余数的除法》教案
- 苹果6发布时间_iPhone12promax11月6日几点预售 11.6苹果12mini预售时间
- 柳暗花明 | 海归小硕的求职之路
- scintilla 中的代码折叠功能的使用
- 智能开关如何实现双控
- 郑州大学计算机课程表查询,郑州大学研究生课程表
- Pexels Videos – 可以免费商业使用的短视频
- python特效源代码_人工智能python代码实现魔幻换天视频特效
- 轴承剥离型故障对应的特征频率
- 产品销售成本与产品制造成本的区别
- vue中谷歌地图标记点、聚合点图标自定义
- 【转】FILE *fp fopen 参数
热门文章
- mysql 1215_mysql执行带外键的sql文件时出现mysql ERROR 1215 (HY000): Cannot add foreign key constraint的解决...
- matlab字符和字符串,MATLAB字符和字符串
- 计算机专业研究生应该如何规划,【图片】2020考研,老学长教你如何规划!【计算机考研吧】_百度贴吧...
- 各种抠图动态图片_不用手。自动、智能抠图,图片去背景
- qt调用mysql调用了存储过_Qt调用Server SQL中的存储过程
- oracle几个网络,ORACLE网络的几个重点概念
- mysql中为表创建副本_如何为数据库建立一个副本?
- 市直系统推荐市级以上表彰的_推荐市级以及以上教学方面表彰的细则
- 在 Windows 命令提示符下启动 MySQL:net start mysql 发生系统错误 5。 拒绝访问。解决方式小结
- Java 格式转换:利用格式转换实现随机数生成随机 char 字母及 string 字母串