上周写了段图片自动轮播的代码,感受应用的局限性仍是挺大,实习期间一直在捣鼓移动端网页的开发,这周试了试原生JS实现左右滑动的图片轮播,在网上找了不少滑动插件诸如swipe,hammer,Quo,JQM 用着都不太理想, 最后一咬牙仍是本身码,先上DEMO, 用手机打开demo查看效果或用Chrome模拟(在iPhone上测试没有问题,可是安卓上彷佛有时会有卡顿,不知道是我手机的问题仍是代码兼容性有问题,还有待测试)。
原生JS实现触控滑动(swipe)图片轮播DEMOhtml
左右触控的动做识别关键在于HTML5的touch事件中手指坐标的偏移量,判断touchmove与touchstart之间手指(touchs)的位置偏移便可判断出是左滑(偏移为正)仍是右滑(偏移为负),淡入淡出的方法实现仍是用我以前使用的CSS3 transition 详情可见我上篇博客:
基于CSS3实现淡入(fadeIn)淡出(fadeOut)效果
本文只是简单的使用了html5的touch API , 利用touch事件实现更复杂的交互(好比相似幻灯片或者原生应用的手指跟随的翻页效果可看我这篇博客:移动端原生JS实现手指跟随的触控滑动
话休絮烦上代码:html5
HTMLweb
<!-- images box --!> <div id="imgs"> <div id="bg1" class="bg"></div> <div id="bg2" class="bg"></div> <div id="bg3" class="bg"></div> <div id="bg4" class="bg"></div> <div id="bg5" class="bg"> </div> </div> <!-- ths pagination box --!> <div class="pagination-panel"> <ul class="pagination"> <li id="dot_0" class="page-dot"></li> <li id="dot_1" class="page-dot"></li> <li id="dot_2" class="page-dot"></li> <li id="dot_3" class="page-dot"></li> <li id="dot_4" class="page-dot"></li> </ul> </div>
CSS:segmentfault
.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:ide
//封装的对象接受全部图片的盒元素与触发切换的最小滑动距离做为参数 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)