上周写了段图片自动轮播的代码,感觉应用的局限性还是挺大,实习期间一直在捣鼓移动端网页的开发,这周试了试原生JS实现左右滑动的图片轮播,在网上找了很多滑动插件诸如swipe,hammer,Quo,JQM 用着都不太理想, 最后一咬牙还是自己码,先上DEMO, 用手机打开demo查看效果或用Chrome模拟(在iPhone上测试没有问题,但是安卓上似乎有时会有卡顿,不知道是我手机的问题还是代码兼容性有问题,还有待测试)。
原生JS实现触控滑动(swipe)图片轮播DEMO
左右触控的动作识别关键在于HTML5的touch事件中手指坐标的偏移量,判断touchmove与touchstart之间手指(touchs)的位置偏移即可判断出是左滑(偏移为正)还是右滑(偏移为负),淡入淡出的方法实现还是用我之前使用的CSS3 transition 详情可见我上篇博客:
基于CSS3实现淡入(fadeIn)淡出(fadeOut)效果
本文只是简单的使用了html5的touch API , 利用touch事件实现更复杂的交互(比如类似幻灯片或者原生应用的手指跟随的翻页效果可看我这篇博客:移动端原生JS实现手指跟随的触控滑动
话休絮烦上代码:
HTML
CSS:
.bg {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
-webkit-transition: opacity .9s linear;
-moz-transition: opacity .9s linear;
-o-transition: opacity .9s linear;
transition: opacity .9s linear;
opacity:0;
filter: alpha(opacity=0);
}
#bg1 {
background: url(http://i3.tietuku.com/6c65325bbf87eb84.jpg) no-repeat;
background-size: cover;
}
#bg2 {
background: url(http://i3.tietuku.com/a72ff6249b76a87e.jpg) no-repeat;
background-size: cover;
}
#bg3 {
background: url(http://i3.tietuku.com/eba2fb18598fa5ca.jpg) no-repeat;
background-size: cover;
}
#bg4 {
background: url(http://i3.tietuku.com/780c4c17e7bcc81d.jpg) no-repeat;
background-size: cover;
}
#bg5 {
background: url(http://i3.tietuku.com/8f4305f8f9538037.jpg) no-repeat;
background-size: cover;
}
.fadein {
opacity: 100;
filter: alpha(opacity=100);
}
.pagination {
width: auto;
display: table;
margin: 0 auto
}
.pagination-panel {
width: 100%;
position: fixed;
bottom: 50px;
z-index: 100;
height: auto
}
.pagination li {
border-radius: 15px;
height: 15px;
width: 15px;
background: #fff;
float: left;
margin-right: 10px;
list-style-type: none
}
.pagination li.active {
background: #52c6d8
}
.pagination li:last-child {
margin-right: 0
}
JS:
//封装的对象接受所有图片的盒元素与触发切换的最小滑动距离作为参数
var ImageSwiper = function(imgs, minRange) {
this.imgBox = imgs
this.imgs = imgs.children
this.cur_img = 1 //起始图片设为1 ,而非0,将在图片显示方法中作-1处理
this.ready_moved = true //判断每次滑动开始的标记变量
this.imgs_count = this.imgs.length
this.touchX //触控开始的手指最初落点
this.minRange = Number(minRange)
this.fadeIn //图片切换的方式,这里使用淡入淡出
this.fadeOut
this.bindTouchEvn() //初始化绑定滑动事件
this.showPic(this.cur_img) //显示图片方法,注意其中图片编号的-1处理
}
ImageSwiper.prototype.bindTouchEvn = function() {
this.imgBox.addEventListener('touchstart', this.touchstart.bind(this), false)
this.imgBox.addEventListener('touchmove', this.touchmove.bind(this), false)
this.imgBox.addEventListener('touchend', this.touchend.bind(this), false)
}
ImageSwiper.prototype.touchstart = function(e) {
if (this.ready_moved) {
var touch = e.touches[0];
this.touchX = touch.pageX;
this.ready_moved = false;
}
}
ImageSwiper.prototype.touchmove = function(e) {
e.preventDefault();
var minRange = this.minRange
var touchX = this.touchX
var imgs_count = this.imgs_count
if (!this.ready_moved) {
var release = e.changedTouches[0];
var releasedAt = release.pageX;
if (releasedAt + minRange < touchX) {
this.ready_moved = true;
if (this.cur_img > (imgs_count - 1)) {
this.cur_img = 0;
}
this.cur_img++;
this.showPic(this.cur_img);
} else if (releasedAt - minRange > touchX) {
if (this.cur_img <= 1) {
this.cur_img = imgs_count + 1
}
this.cur_img--;
this.showPic(this.cur_img);
this.ready_moved = true;
}
}
}
ImageSwiper.prototype.touchend = function(e) {
e.preventDefault();
var minRange = this.minRange
var touchX = this.touchX
var imgs_count = this.imgs_count
if (!this.ready_moved) {
var release = e.changedTouches[0];
var releasedAt = release.pageX;
if (releasedAt + minRange < touchX) {
this.ready_moved = true;
if (this.cur_img > (imgs_count - 1)) {
this.cur_img = 0;
}
this.cur_img++;
showPic(this.cur_img);
} else if (releasedAt - minRange > touchX) {
if (this.cur_img <= 1) {
this.cur_img = imgs_count + 1
}
this.cur_img--;
showPic(this.cur_img);
this.ready_moved = true;
}
}
}
//在样式表中设置好 .fadeIn 的透明度为0
ImageSwiper.prototype.fadeIn = function(e) {
e.classList.add("fadeIn")
}
ImageSwiper.prototype.fadeOut = function(e) {
Array.prototype.forEach.call(e, function(e) {
e.className = "bg"
})
}
ImageSwiper.prototype.showPic = function(cur_img) {
this.hidePics(this.imgs)
//得到图片元素的真实索引
var index = cur_img - 1
if (document.getElementsByClassName("active")[0]) {
var active = document.getElementsByClassName("active")[0];
active.classList.remove("active")
}
console.log(this.cur_img)
document.getElementById("dot_" + index).classList.add("active");
this.fadeIn(this.imgs[index]);
}
ImageSwiper.prototype.hidePics = function(e) {
this.fadeOut(e)
}
//传参
var imgs = new ImageSwiper(document.getElementById('imgs'), 30)