在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

只是做了简单通用设置,可以自定义扩充。

 .veSlider {
position: relative;
list-style: none;
margin:;
padding:;
width: 100%;
overflow: hidden;
}
.veSlider > li {
position: absolute;
top:;
left:;
list-style: none;
overflow: hidden;
height: inherit;
}

2)HTML

为了实现方便,我直接将相关的ul与li标签写死在页面中。

高级点的话,可以通过JS脚本动态输出,并且在输出的时候可以做图片预加载等处理。

height写在了style中,因为各种情况下的高度是不同的,所以自定义设置

 <ul class="veSlider" style="height:180px" id="veSlider">
<li>
<a href="http://www.cnblogs.com/strick/">
<img src="img/banner.jpg" width="100%" />
</a>
</li>
</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 自动移动的时候用.4
this.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、目前只支持左右滑动,上下滑动的话要做些更灵活的修改

还有很多方面可以改进,这里就不列举了。

自制 移动端 纯原生 Slider滑动插件的更多相关文章

  1. 移动端纯原生JS不依赖ajax后台服务器实现省市县三级联动

    最近好多天没有更新文章,是因为公司的项目忙的不行.今天有点时间,就突然想起在移动端项目中遇到三级联动的问题,网上查了很多资料,都是依赖各种插件,或者晦涩难于理解.于是,自己决定写一个出来. 当然,没有 ...

  2. 纯原生js移动端图片压缩上传插件

    前段时间,同事又来咨询一个问题了,说手机端动不动拍照就好几M高清大图,上传服务器太慢,问问我有没有可以压缩图片并上传的js插件,当然手头上没有,别慌,我去网上搜一搜. 结果呢,呵呵...诶~又全是基于 ...

  3. 纯原生js移动端城市选择插件

    接着上一篇纯js移动端日期选择插件,话说今天同事又来咨询省市县联动的效果在移动端中如何实现,还是老样子,百度上一搜,诶~又全是基于jquery.zepto的,更加可恨的是大多数都是PC版的,三个sel ...

  4. 移动端lCalendar纯原生js日期时间选择器

    网上找过很多的移动端基于zepto或jquery的日期选择器,在实际产品中也用过一两种,觉得都不太尽如人意,后来果断选择了H5自己的日期input表单,觉得还可以,至少不用引用第三方插件了,性能也不错 ...

  5. 移动端触摸滑动插件Swiper

    移动端触摸滑动插件Swiper 04/02/2015 一.了解Swiper 目前移动端项目一般都需要具有触屏焦点图的效果,如果你也需要实现这一功能的话,Swiper是一个不错的选择. 1.他不需要加载 ...

  6. 移动端触摸滑动插件Swiper使用指南

    Swiper是一款开源.免费.功能十分强大的移动端内容触摸滑动插件,目前的最新版本是Swiper4.Swiper主要面向的是手机.平板电脑等移动设备,帮助开发者轻松实现触屏焦点图.触屏Tab切换.触屏 ...

  7. photoSlider-html5原生js移动开发轮播图-相册滑动插件

    简单的移动端图片滑动切换浏览插件 分别引用css文件和js文件 如: <link rel="stylesheet" type="text/css" hre ...

  8. swiper嵌套小demo(移动端触摸滑动插件)

    swiper(移动端触摸滑动插件) tip:自己敲得Swiper 的小demo,可以复制粘贴看看效果哦. swiper的js包css包下链接地址 :  https://github.com/Clear ...

  9. Swipe-移动端触摸滑动插件swipe.js

    原文链接:http://caibaojian.com/swipe.html 插件特色 viaswipe.JS是一个比较有名的触摸滑动插件,它能够处理内容滑动,支持自定义选项,你可以让它自动滚动,控制滚 ...

随机推荐

  1. ActionMapping

    在Struts中,ActionServlet只是任务的分派者,它依请求分配任务给其它的对象来执行,而分配的依据是请求的URI以及struts-config.xml的<action-mapping ...

  2. *POJ1830 高斯消元

    开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8010   Accepted: 3161 Description ...

  3. CSS3动画快速实现

    在工作或者平时做demo中,经常会遇到做一些简单的动画.初级前端同学可能就会有些棘手了. 在这里我发现了一个网上笔记实用且简单易上手的动画库.与大家共享一下: 更多请查看:http://anicoll ...

  4. [转]html5表单上传控件Files API

    表单上传控件:<input type="file" />(IE9及以下不支持下面这些功能,其它浏览器最新版本均已支持.) 1.允许上传文件数量 允许选择多个文件:< ...

  5. windows上面捕获声卡数据

    转自:http://shanewfx.github.io/blog/2013/08/14/caprure-audio-on-windows/ 前一段时间接到一个任务,需要采集到声卡的输出信号,以便与麦 ...

  6. java学习笔记(3)之面向对象(1)

    下面来谈谈我对面向对象的一些理解和总结. 1.什么叫面向对象?我自己的理解就是一种编程思想,强调对象,是一种思考问题的思维模式.在学习面向对象的时候,我们要建立起自己面向对象的思维模式. (1).先整 ...

  7. div+css中clear用法

    一开始用clear属性,只是跟float相对使用,今天看视频的时候还是不大明白,查了下资料原来是这样的哦,看咯. clear属性值有四个clear:both|left|right|none; 作用:该 ...

  8. 玩转SQL Server复制回路の变更数据类型、未分区表转为分区表

    玩转SQL Server复制回路の变更数据类型.未分区表转为分区表 复制的应用: 初级应用:读写分离.数据库备份 高级应用:搬迁大型数据库(跨机房).变更数据类型.未分区表转为分区表 京东的复制专家 ...

  9. Kosaraju 算法检测有向图的强连通性

    给定一个有向图 G = (V, E) ,对于任意一对顶点 u 和 v,有 u --> v 和 v --> u,亦即,顶点 u 和 v 是互相可达的,则说明该图 G 是强连通的(Strong ...

  10. 一个小白App开发需要了解的基本技术

    本文针对小白用户对App做一个简单的介绍,首先要了解App都有哪些类型,不同的类型适用于哪些需求,用户可以根据自己的需求选择不同的App开发. 一 App有哪些形式 WebApp:简单来说,Web A ...