关于轮播图:原生JS实现轮播图

轮播图原理就是图片的挪动。所有轮播图片横向排列,在一个窗口中显示一张图片,窗口外的图片暗藏,每一次一排图片就是挪动一张图片的间隔,切换到下一张图片,即可实现图片轮播。 图片的挪动有两种形式: translate 实现的图片挪动position定位实现图片的偏移图片的自动播放,那必然用到定时器吧,而且是距离定时器 setInterval 该案例实现成果: 图片自动播放点击两头圆点按钮,实现图片任意切换点击左右箭头按钮,实现图片左右切换图片的切换对应小圆点的款式变动,即每一个小圆点对应一张图片先来看一下效果图: html格局:<!-- 引入css款式 --><link rel="stylesheet" href="./demo.css"><div class="banner_container"> <!-- 6张图片 --> <ul class="img_box"> <li><img src="图片4" alt=""></li> <li><img src="图片1" alt=""></li> <li><img src="图片2" alt=""></li> <li><img src="图片3" alt=""></li> <li><img src="图片4" alt=""></li> <li><img src="图片1" alt=""></li> </ul> <!-- 两头圆点 --> <ul class="sel_box"> <!-- 自定义属性 --> <li data-index="0"></li> <li data-index="1"></li> <li data-index="2"></li> <li data-index="3"></li> </ul> <!-- 左箭头 --> <div class="left_btn">&lt;</div> <!-- 右箭头 --> <div class="right_btn">&gt;</div></div><!-- 引入js代码 --><script src="./demo.js"></script>大家别被骗了,这里轮播图只实现4张图片的播放,至于另外多出的两张,其实另有用途 第一张图片搁置的其实四张轮播图中的最初一张,第6张图片其实是四张轮播图中的第一张,目标很简略,就是为了实现图片无缝轮播,上面用到的中央会阐明哈 CSS款式* { padding: 0; margin: 0; box-sizing: border-box;}.banner_container { position: relative; margin: 100px; width: 400px; height: 250px; /* 超出暗藏 */ overflow: hidden; }ul.img_box { position: absolute; left: 0; top: 0; /* html中的第一张图片不是咱们想要显示,第二张才是咱们轮播图的第一张图片因而要让这排图片往左挪动一张图片的间隔 */ transform: translateX(-400px);}.img_box li { float: left; list-style: none;}/* 图片大小 */.img_box li img { width: 400px;}/* 小圆点 */.sel_box { position: absolute; bottom: 15px; left: 50%; transform: translateX(-50%);}.sel_box li { list-style: none; /* 转换为行内块元素 -- 一行显示 */ display: inline-block; width: 10px; height: 10px; background-color: pink; margin-right: 3px; border-radius: 5px; transition: all 0.4s;}/* 左箭头 */.left_btn { position: absolute; top: 50%; left: 0; transform: translateY(-50%); width: 25px; height: 30px; background-color: #fff; line-height: 30px; padding-left: 3px; /* 将鼠标款式改为小手 */ cursor: pointer;}.right_btn { position: absolute; top: 50%; left: 375px; transform: translateY(-50%); width: 25px; height: 30px; background-color: #fff; line-height: 30px; padding-left: 5px; cursor: pointer;}/* 以后图片的小图点款式 */.sel_box .cur { background-color: red!important; transform: scale(1.3);}这是简略的css款式,大家能够依据本人爱好自行编写款式 ...

May 5, 2021 · 3 min · jiezi

Flutter之自定义封装轮播图

黄沙百战穿金甲不破楼兰终不还 前言通过封装PageView+Timer实现无限轮播,手动拖拽时停止定时器功能,拖拽完成后开启定时器。 功能自动轮播手动轮播指示器功能展示 代码实现轮播组件的构造方法 class Carousel extends StatefulWidget { final List<BannerModel> banners; // BannerModel是每个item对应的模型 必传参数 final OnTapBannerItem onTap, // `必传参数` 传入点击每个item的方法 final Color indicatorNormalColor;// 指示器球的正常颜色 final Color indicatorCurrentColor;// 指示器球的当前颜色 final double indicatorWidth;// 指示器球的宽高 final double indicatorMargin;// 指示器球之间间距 final bool hiddenIndicator;// 是否影藏指示器 final bool hiddenIndicatorForSingle;// 单个图片是否影藏指示器 final bool autoScroll; // 是否循环 final int seconds; // 轮播间隔 Carousel( {Key key, @required this.banners, @required this.onTap, this.seconds = 5, // 不传 默认5秒 轮播一次 this.autoScroll = true, this.hiddenIndicator = false, this.hiddenIndicatorForSingle = true, this.indicatorWidth = 6, this.indicatorMargin = 1.5, this.indicatorCurrentColor = Colors.white, this.indicatorNormalColor = Colors.grey}) : super(key: key); @override State<StatefulWidget> createState() { return _BannerState(); }}组件状态实现方法 ...

July 9, 2019 · 3 min · jiezi

jQuery插件--web端轮播图

效果地址HTML<div id=“slider” class=“slider”></div><script> $(function () { $(’#slider’).sliders({ imgArr: [’./resource/banner1.jpg’, ‘./resource/banner2.jpg’, ‘./resource/banner3.jpg’], autoLoop: true, current: 1, time: 4000, vWidth: 824 }) });</script>cssJS代码;(function ($, window, document, undefined) { ‘use strict’; function Sliders(element, options) { this.element = element; this.options = { vWidth: options.vWidth || element.width(), current: options.current || 1, imgArr: options.imgArr, len: options.imgArr.length, autoLoop: options.autoLoop, time: options.time || 4000 }; this.init(); } Sliders.prototype = { constructor: Sliders, init: function () { this.createHtml(); this.bindEvent(); this.hackLoop(); }, createHtml: function () { var me = this; var content = []; var imgArr = me.options.imgArr, len = me.options.len, current = me.options.current; content.push("<button type=‘button’ class=‘preBtn’ id=‘preBtn’>上</button>"); content.push("<button type=‘button’ class=‘nextBtn’ id=‘nextBtn’>下</button>"); content.push("<ul class=‘sliderUl’>"); for (var i = 0; i < len; i++) { content.push("<li class=‘sliderLi’><img class=‘block’ src=" + imgArr[i] + “>” + i + “</li>”) } content.push("<li class=‘sliderLi’><img class=‘block’ src=" + imgArr[0] + “>” + i + “</li></ul>”); content.push("<ul class=‘pointer’>"); for (var i = 1, len1 = len + 1; i < len1; i++) { if (current !== i) { content.push("<li data-index=" + i + “></li>”); } else { content.push("<li class=‘current’ data-index=" + i + “></li>”); } } content.push("</ul>"); me.element.html(content.join(’’)); }, bindEvent: function () { var me = this; me.element.on(‘mouseenter’, ‘.sliderUl’, function () { clearInterval(me.timer); }); me.element.on(‘click’, ‘.pointer li’, function () { clearInterval(me.timer); var index = parseInt($(this).data(‘index’)); me.goPage(index); }); me.element.on(‘mouseleave’, ‘.sliderUl’, function () { me.hackLoop(); }); me.element.on(‘click’, ‘#preBtn’, function () { clearInterval(me.timer); var i = me.options.current, len = me.options.len; me.options.current = –i === 0 ? len-1 : i-1; me.loop(); }); me.element.on(‘click’, ‘#nextBtn’, function () { clearInterval(me.timer); var i = me.options.current, len = me.options.len; me.options.current = i === len ? 0 : i; me.loop(); }); }, loop: function () { var me = this; var i = me.options.current, vWidth = me.options.vWidth, len = me.options.len; console.log(i); me.element.children(’.sliderUl’).css({ “-webkit-transform”: “translateX(” + (-i * vWidth) + “px)”, “transform”: “translateX(” + (-i * vWidth) + “px)”, “transition-duration”: “0.4s”, “transition-timing-function”: “ease-in”, “transition-property”: “transform” }); me.element.children(’.pointer’).children(“li”).removeClass(“current”); me.element.children(’.pointer’).children(“li”).eq(i === len ? 0 : i).addClass(“current”); if (me.options.current === len) { setTimeout(function () { me.element.children(’.sliderUl’).css({ “-webkit-transform”: “translateX(0px)”, “transform”: “translateX(0px)”, “transition-duration”: “none”, “transition-timing-function”: “none”, “transition-property”: “none” }); //时间必须不小于动画所需时间 }, 400); } me.options.current = (len !== i) ? ++i : 1; }, hackLoop: function () { var me = this; if (me.options.autoLoop) { me.timer = setInterval(function () { me.loop(); }, me.options.time); } }, goPage: function (index) { var me = this; var vWidth = me.options.vWidth; me.options.current = index; me.element.children(’.sliderUl’).css({ “-webkit-transform”: “translateX(” + (-(index - 1) * vWidth) + “px)”, “transform”: “translateX(” + (-(index - 1) * vWidth) + “px)”, “transition-duration”: “0.4s”, “transition-timing-function”: “ease-in”, “transition-property”: “transform” }); me.element.children(’.pointer’).children(“li”).removeClass(“current”); me.element.children(’.pointer’).children(“li”).eq(index - 1).addClass(“current”); } }; $.fn.sliders = function (options) { return new Sliders($(this), options); }})(jQuery, window, document); ...

April 3, 2019 · 3 min · jiezi

原生 js 实现移动端 Touch 轮播图

Touch 轮播图touch轮播图其实就是通过手指的滑动,来左右切换轮播图,下面我们通过一个案例,来实现下。1. html 结构结构上,还是用ul、li来存放轮播图片,ol、li来存放轮播小圆点:2. 样式初始化html的一些标签,都会有一些默认样式,比如body标签默认是有一个边距的,为了不影响美观,我们需要清除掉。/* 清除标签默认边距 /body,ul,li,ol,img { margin: 0; padding: 0;}/ 清除 ul 等标签前面的“小圆点” /ul,li,ol { list-style-type: none;}/ 图片自适应 /img { width: 100%; height: auto; border: none; / ie8 / display: block; -ms-interpolation-mode: bicubic; /为了照顾ie图片缩放失真/}3. 添加样式在前面讲特效的时候,我们说过如何使用原生js实现移一个轮播图的概念,但是当时的方式是通过li浮动,这里给大家介绍一种新的方——定位。思路:给ul外层的盒子一个相对定位;这里的ul高度不能写死,它应该是li撑开的高度,但是由于li绝对定位,没办法撑开这个高度,所以这里的ul需要在js里面动态设置高度;给li设置相对定位,并且left、top都为0,再给li添加一个transform:translateX(300%)属性,目的是初始化显示的图片为空,然后在js里只需要动态设置每个li的translateX值,即可实现轮播;设置小圆点区域,因为小圆点个数未知,所以ol的宽度也未知,想要让一个未知宽度的盒子水平居中,可以使用absolute定位结合left百分比的方式实现;给ol下面的li设置一个宽高添加圆角边框属性,并且左浮动,这样就能显示一排空心的小圆点了;最后,添加一个样式类,里面设置一个背景属性,用来显示当前展示图片对应的小圆点。/ 轮播图最外层盒子 /.carousel { position: relative; overflow: hidden;}.carousel ul { / 这个高度需要在JS里面动态添加 /}.carousel ul li { position: absolute; width: 100%; left: 0; top: 0; / 使用 transform:translaX(300%) 暂时将 li 移动到屏幕外面去*/ -webkit-transform: translateX(300%); transform: translateX(300%);}/* 小圆点盒子 /.carousel .points { / 未知宽度的盒子,使用 absolute 定位,结合 transform 的方式进行居中 / position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%);}/ 小圆点 /.carousel .points li { width: 5px; height: 5px; border-radius: 50%; border: 1px solid #fff; float: left; margin: 0 2px;}/ 选中小圆点的样式类 */.carousel .points li.active { background-color: #fff;}4. js 准备工作先不考虑别的,js在初始化的时候,首先要做的就是给ul添加上一个高度,不然图片是不显示的。给UL动态设置高度动态生成小圆点 (根据图片的张数创建小圆点个数,i=0 添加active)初始化三个li的基本位置定义三个变量,分别用来存储三个li的下(left存储最后一张图片的下标,center和right分别存储第一张和第二张的下标)通过数组[下标]的方式给三个li设置定位后left方向的位置var carousel = document.querySelector(’.carousel’);var carouselUl = carousel.querySelector(‘ul’);var carouselLis = carouselUl.querySelectorAll(’li’);var points = carousel.querySelector(‘ol’);// 屏幕的宽度(轮播图显示区域的宽度)var screenWidth = document.documentElement.offsetWidth;// 1- ul设置高度carouselUl.style.height = carouselLis[0].offsetHeight + ‘px’;// 2- 生成小圆点for(var i = 0; i < carouselLis.length; i++){ var li = document.createElement(’li’); if(i == 0){ li.classList.add(‘active’); }// points.appendChild(li);}// 3- 初始三个 li 固定的位置var left = carouselLis.length - 1;var center = 0;var right = 1;// 归位carouselLis[left].style.transform = ’translateX(’+ (-screenWidth) +‘px)’;carouselLis[center].style.transform = ’translateX(0px)’;carouselLis[right].style.transform = ’translateX(’+ screenWidth +‘px)’;效果图:5. 添加定时器,让图片动起来轮播图都会自己轮播,所以需要用到定时器,每隔一段时间执行一次轮转函数。添加定时器,定时器里面轮转下标极值判断设置过渡(替补的那张不需要过渡)归位小圆点焦点联动var timer = null;// 调用定时器timer = setInterval(showNext, 2000);// 轮播图片切换function showNext(){ // 轮转下标 left = center; center = right; right++; // 极值判断 if(right > carouselLis.length - 1){ right = 0; } //添加过渡 carouselLis[left].style.transition = ’transform 1s’; carouselLis[center].style.transition = ’transform 1s’; // 右边的图片永远是替补的,不能添加过渡 carouselLis[right].style.transition = ’none’; // 归位 carouselLis[left].style.transform = ’translateX(’+ (-screenWidth) +‘px)’; carouselLis[center].style.transform = ’translateX(0px)’; carouselLis[right].style.transform = ’translateX(’+ screenWidth +‘px)’; // 自动设置小圆点 setPoint();}// 动态设置小圆点的active类var pointsLis = points.querySelectorAll(’li’);function setPoint(){ for(var i = 0; i < pointsLis.length; i++){ pointsLis[i].classList.remove(‘active’); } pointsLis[center].classList.add(‘active’);}效果图:6. touch 滑动移动端的轮播图,配合touch滑动事件,效果更加友好。分别绑定三个touch事件touchstart里面记录手指的位置,清除定时器,记录时间touchmove里面获取差值,同时清除过渡,累加上差值的值touchend里面判断是否滑动成功,滑动的依据是滑动的距离(绝对值)超过屏幕的三分之一或者滑动的时间小于300毫秒同时距离大于30(防止点击就跑)的时候都认为是滑动成功在滑动成功的条件分支里面在判断滑动的方向,根据方向选择调用上一张还是下一张的逻辑在滑动失败的条件分支里面添加上过渡,重新进行归位重启定时器var carousel = document.querySelector(’.carousel’);var carouselUl = carousel.querySelector(‘ul’);var carouselLis = carouselUl.querySelectorAll(’li’);var points = carousel.querySelector(‘ol’);// 屏幕的宽度var screenWidth = document.documentElement.offsetWidth;var timer = null;// 设置 ul 的高度carouselUl.style.height = carouselLis[0].offsetHeight + ‘px’;// 动态生成小圆点for (var i = 0; i < carouselLis.length; i++) { var li = document.createElement(’li’); if (i == 0) { li.classList.add(‘active’); } points.appendChild(li);}// 初始三个固定的位置var left = carouselLis.length - 1;var center = 0;var right = 1;// 归位(多次使用,封装成函数)setTransform();// 调用定时器timer = setInterval(showNext, 2000);// 分别绑定touch事件var startX = 0; // 手指落点var startTime = null; // 开始触摸时间carouselUl.addEventListener(’touchstart’, touchstartHandler); // 滑动开始绑定的函数 touchstartHandlercarouselUl.addEventListener(’touchmove’, touchmoveHandler); // 持续滑动绑定的函数 touchmoveHandlercarouselUl.addEventListener(’touchend’, touchendHandeler); // 滑动结束绑定的函数 touchendHandeler// 轮播图片切换下一张function showNext() { // 轮转下标 left = center; center = right; right++; // 极值判断 if (right > carouselLis.length - 1) { right = 0; } //添加过渡(多次使用,封装成函数) setTransition(1, 1, 0); // 归位 setTransform(); // 自动设置小圆点 setPoint();}// 轮播图片切换上一张function showPrev() { // 轮转下标 right = center; center = left; left–; // 极值判断 if (left < 0) { left = carouselLis.length - 1; } //添加过渡 setTransition(0, 1, 1); // 归位 setTransform(); // 自动设置小圆点 setPoint();}// 滑动开始function touchstartHandler(e) { // 清除定时器 clearInterval(timer); // 记录滑动开始的时间 startTime = Date.now(); // 记录手指最开始的落点 startX = e.changedTouches[0].clientX;}// 滑动持续中function touchmoveHandler(e) { // 获取差值 自带正负 var dx = e.changedTouches[0].clientX - startX; // 干掉过渡 setTransition(0, 0, 0); // 归位 setTransform(dx);}// 滑动结束function touchendHandeler(e) { // 在手指松开的时候,要判断当前是否滑动成功 var dx = e.changedTouches[0].clientX - startX; // 获取时间差 var dTime = Date.now() - startTime; // 滑动成功的依据是滑动的距离(绝对值)超过屏幕的三分之一 或者滑动的时间小于300毫秒同时滑动的距离大于30 if (Math.abs(dx) > screenWidth / 3 || (dTime < 300 && Math.abs(dx) > 30)) { // 滑动成功了 // 判断用户是往哪个方向滑 if (dx > 0) { // 往右滑 看到上一张 showPrev(); } else { // 往左滑 看到下一张 showNext(); } } else { // 添加上过渡 setTransition(1, 1, 1); // 滑动失败了 setTransform(); } // 重新启动定时器 clearInterval(timer); // 调用定时器 timer = setInterval(showNext, 2000);}// 设置过渡function setTransition(a, b, c) { if (a) { carouselLis[left].style.transition = ’transform 1s’; } else { carouselLis[left].style.transition = ’none’; } if (b) { carouselLis[center].style.transition = ’transform 1s’; } else { carouselLis[center].style.transition = ’none’; } if (c) { carouselLis[right].style.transition = ’transform 1s’; } else { carouselLis[right].style.transition = ’none’; }}// 封装归位function setTransform(dx) { dx = dx || 0; carouselLis[left].style.transform = ’translateX(’ + (-screenWidth + dx) + ‘px)’; carouselLis[center].style.transform = ’translateX(’ + dx + ‘px)’; carouselLis[right].style.transform = ’translateX(’ + (screenWidth + dx) + ‘px)’;}// 动态设置小圆点的active类var pointsLis = points.querySelectorAll(’li’);function setPoint() { for (var i = 0; i < pointsLis.length; i++) { pointsLis[i].classList.remove(‘active’); } pointsLis[center].classList.add(‘active’);}效果图: ...

January 3, 2019 · 3 min · jiezi

原生js实现移动端Touch轮播图

Touch 轮播图touch轮播图其实就是通过手指的滑动,来左右切换轮播图,下面我们通过一个案例,来实现下。1. html 结构结构上,还是用ul、li来存放轮播图片,ol、li来存放轮播小圆点:2. 样式初始化html的一些标签,都会有一些默认样式,比如body标签默认是有一个边距的,为了不影响美观,我们需要清除掉。/* 清除标签默认边距 /body,ul,li,ol,img { margin: 0; padding: 0;}/ 清除 ul 等标签前面的“小圆点” /ul,li,ol { list-style-type: none;}/ 图片自适应 /img { width: 100%; height: auto; border: none; / ie8 / display: block; -ms-interpolation-mode: bicubic; /为了照顾ie图片缩放失真/}3. 添加样式在前面讲特效的时候,我们说过如何使用原生js实现移一个轮播图的概念,但是当时的方式是通过li浮动,这里给大家介绍一种新的方——定位。思路:给ul外层的盒子一个相对定位;这里的ul高度不能写死,它应该是li撑开的高度,但是由于li绝对定位,没办法撑开这个高度,所以这里的ul需要在js里面动态设置高度;给li设置相对定位,并且left、top都为0,再给li添加一个transform:translateX(300%)属性,目的是初始化显示的图片为空,然后在js里只需要动态设置每个li的translateX值,即可实现轮播;设置小圆点区域,因为小圆点个数未知,所以ol的宽度也未知,想要让一个未知宽度的盒子水平居中,可以使用absolute定位结合left百分比的方式实现;给ol下面的li设置一个宽高添加圆角边框属性,并且左浮动,这样就能显示一排空心的小圆点了;最后,添加一个样式类,里面设置一个背景属性,用来显示当前展示图片对应的小圆点。/ 轮播图最外层盒子 /.carousel { position: relative; overflow: hidden;}.carousel ul { / 这个高度需要在JS里面动态添加 /}.carousel ul li { position: absolute; width: 100%; left: 0; top: 0; / 使用 transform:translaX(300%) 暂时将 li 移动到屏幕外面去*/ -webkit-transform: translateX(300%); transform: translateX(300%);}/* 小圆点盒子 /.carousel .points { / 未知宽度的盒子,使用 absolute 定位,结合 transform 的方式进行居中 / position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%);}/ 小圆点 /.carousel .points li { width: 5px; height: 5px; border-radius: 50%; border: 1px solid #fff; float: left; margin: 0 2px;}/ 选中小圆点的样式类 */.carousel .points li.active { background-color: #fff;}4. js 准备工作先不考虑别的,js在初始化的时候,首先要做的就是给ul添加上一个高度,不然图片是不显示的。给UL动态设置高度动态生成小圆点 (根据图片的张数创建小圆点个数,i=0 添加active)初始化三个li的基本位置定义三个变量,分别用来存储三个li的下(left存储最后一张图片的下标,center和right分别存储第一张和第二张的下标)通过数组[下标]的方式给三个li设置定位后left方向的位置var carousel = document.querySelector(’.carousel’);var carouselUl = carousel.querySelector(‘ul’);var carouselLis = carouselUl.querySelectorAll(’li’);var points = carousel.querySelector(‘ol’);// 屏幕的宽度(轮播图显示区域的宽度)var screenWidth = document.documentElement.offsetWidth;// 1- ul设置高度carouselUl.style.height = carouselLis[0].offsetHeight + ‘px’;// 2- 生成小圆点for(var i = 0; i < carouselLis.length; i++){ var li = document.createElement(’li’); if(i == 0){ li.classList.add(‘active’); }// points.appendChild(li);}// 3- 初始三个 li 固定的位置var left = carouselLis.length - 1;var center = 0;var right = 1;// 归位carouselLis[left].style.transform = ’translateX(’+ (-screenWidth) +‘px)’;carouselLis[center].style.transform = ’translateX(0px)’;carouselLis[right].style.transform = ’translateX(’+ screenWidth +‘px)’;效果图:5. 添加定时器,让图片动起来轮播图都会自己轮播,所以需要用到定时器,每隔一段时间执行一次轮转函数。添加定时器,定时器里面轮转下标极值判断设置过渡(替补的那张不需要过渡)归位小圆点焦点联动var timer = null;// 调用定时器timer = setInterval(showNext, 2000);// 轮播图片切换function showNext(){ // 轮转下标 left = center; center = right; right++; // 极值判断 if(right > carouselLis.length - 1){ right = 0; } //添加过渡 carouselLis[left].style.transition = ’transform 1s’; carouselLis[center].style.transition = ’transform 1s’; // 右边的图片永远是替补的,不能添加过渡 carouselLis[right].style.transition = ’none’; // 归位 carouselLis[left].style.transform = ’translateX(’+ (-screenWidth) +‘px)’; carouselLis[center].style.transform = ’translateX(0px)’; carouselLis[right].style.transform = ’translateX(’+ screenWidth +‘px)’; // 自动设置小圆点 setPoint();}// 动态设置小圆点的active类var pointsLis = points.querySelectorAll(’li’);function setPoint(){ for(var i = 0; i < pointsLis.length; i++){ pointsLis[i].classList.remove(‘active’); } pointsLis[center].classList.add(‘active’);}效果图:6. touch 滑动移动端的轮播图,配合touch滑动事件,效果更加友好。分别绑定三个touch事件touchstart里面记录手指的位置,清除定时器,记录时间touchmove里面获取差值,同时清除过渡,累加上差值的值touchend里面判断是否滑动成功,滑动的依据是滑动的距离(绝对值)超过屏幕的三分之一或者滑动的时间小于300毫秒同时距离大于30(防止点击就跑)的时候都认为是滑动成功在滑动成功的条件分支里面在判断滑动的方向,根据方向选择调用上一张还是下一张的逻辑在滑动失败的条件分支里面添加上过渡,重新进行归位重启定时器var carousel = document.querySelector(’.carousel’);var carouselUl = carousel.querySelector(‘ul’);var carouselLis = carouselUl.querySelectorAll(’li’);var points = carousel.querySelector(‘ol’);// 屏幕的宽度var screenWidth = document.documentElement.offsetWidth;var timer = null;// 设置 ul 的高度carouselUl.style.height = carouselLis[0].offsetHeight + ‘px’;// 动态生成小圆点for (var i = 0; i < carouselLis.length; i++) { var li = document.createElement(’li’); if (i == 0) { li.classList.add(‘active’); } points.appendChild(li);}// 初始三个固定的位置var left = carouselLis.length - 1;var center = 0;var right = 1;// 归位(多次使用,封装成函数)setTransform();// 调用定时器timer = setInterval(showNext, 2000);// 分别绑定touch事件var startX = 0; // 手指落点var startTime = null; // 开始触摸时间carouselUl.addEventListener(’touchstart’, touchstartHandler); // 滑动开始绑定的函数 touchstartHandlercarouselUl.addEventListener(’touchmove’, touchmoveHandler); // 持续滑动绑定的函数 touchmoveHandlercarouselUl.addEventListener(’touchend’, touchendHandeler); // 滑动结束绑定的函数 touchendHandeler// 轮播图片切换下一张function showNext() { // 轮转下标 left = center; center = right; right++; // 极值判断 if (right > carouselLis.length - 1) { right = 0; } //添加过渡(多次使用,封装成函数) setTransition(1, 1, 0); // 归位 setTransform(); // 自动设置小圆点 setPoint();}// 轮播图片切换上一张function showPrev() { // 轮转下标 right = center; center = left; left–; // 极值判断 if (left < 0) { left = carouselLis.length - 1; } //添加过渡 setTransition(0, 1, 1); // 归位 setTransform(); // 自动设置小圆点 setPoint();}// 滑动开始function touchstartHandler(e) { // 清除定时器 clearInterval(timer); // 记录滑动开始的时间 startTime = Date.now(); // 记录手指最开始的落点 startX = e.changedTouches[0].clientX;}// 滑动持续中function touchmoveHandler(e) { // 获取差值 自带正负 var dx = e.changedTouches[0].clientX - startX; // 干掉过渡 setTransition(0, 0, 0); // 归位 setTransform(dx);}// 滑动结束function touchendHandeler(e) { // 在手指松开的时候,要判断当前是否滑动成功 var dx = e.changedTouches[0].clientX - startX; // 获取时间差 var dTime = Date.now() - startTime; // 滑动成功的依据是滑动的距离(绝对值)超过屏幕的三分之一 或者滑动的时间小于300毫秒同时滑动的距离大于30 if (Math.abs(dx) > screenWidth / 3 || (dTime < 300 && Math.abs(dx) > 30)) { // 滑动成功了 // 判断用户是往哪个方向滑 if (dx > 0) { // 往右滑 看到上一张 showPrev(); } else { // 往左滑 看到下一张 showNext(); } } else { // 添加上过渡 setTransition(1, 1, 1); // 滑动失败了 setTransform(); } // 重新启动定时器 clearInterval(timer); // 调用定时器 timer = setInterval(showNext, 2000);}// 设置过渡function setTransition(a, b, c) { if (a) { carouselLis[left].style.transition = ’transform 1s’; } else { carouselLis[left].style.transition = ’none’; } if (b) { carouselLis[center].style.transition = ’transform 1s’; } else { carouselLis[center].style.transition = ’none’; } if (c) { carouselLis[right].style.transition = ’transform 1s’; } else { carouselLis[right].style.transition = ’none’; }}// 封装归位function setTransform(dx) { dx = dx || 0; carouselLis[left].style.transform = ’translateX(’ + (-screenWidth + dx) + ‘px)’; carouselLis[center].style.transform = ’translateX(’ + dx + ‘px)’; carouselLis[right].style.transform = ’translateX(’ + (screenWidth + dx) + ‘px)’;}// 动态设置小圆点的active类var pointsLis = points.querySelectorAll(’li’);function setPoint() { for (var i = 0; i < pointsLis.length; i++) { pointsLis[i].classList.remove(‘active’); } pointsLis[center].classList.add(‘active’);}效果图: ...

January 2, 2019 · 3 min · jiezi