前端JS案例(二):自动轮播+手动拨动

来源:互联网 发布:jsmd5解密算法 编辑:程序博客网 时间:2024/05/21 08:56

一、自动轮播

1、定义index,记录索引值

2、获取必要的变量:单个元素的宽度、轮播图ul的长度、ul中li的数组

3、设置定时器setInterval,因为是无限轮播,不用清除

4、过度结束,判断index索引值是否有效


html代码:

<!-- 顶部的 轮播图 --><div class="jd_banner"><ul class="banner_images clearfix"><li><a href="#"><img src="images/l8.jpg" alt=""></a></li><li><a href="#"><img src="images/l1.jpg" alt=""></a></li><li><a href="#"><img src="images/l2.jpg" alt=""></a></li><li><a href="#"><img src="images/l3.jpg" alt=""></a></li><li><a href="#"><img src="images/l4.jpg" alt=""></a></li><li><a href="#"><img src="images/l5.jpg" alt=""></a></li><li><a href="#"><img src="images/l6.jpg" alt=""></a></li><li><a href="#"><img src="images/l7.jpg" alt=""></a></li><li><a href="#"><img src="images/l8.jpg" alt=""></a></li><li><a href="#"><img src="images/l1.jpg" alt=""></a></li></ul><ul class="banner_index clearfix"><li class='current'></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul></div>

JS代码:

function banner() {//1 获取变量// 屏幕的宽度var width = document.body.offsetWidth;// console.log(width);\//  获取 轮播图的ulvar moveUl = document.querySelector('.banner_images');// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了// moveUl.style.transition = 'all .3s';// 索引的li标签var indexLiArr = document.querySelectorAll('.banner_index li');// 定义 index 记录 当前的 索引值// 默认 我们的ul 已经 往左边 移动了 一倍的宽度// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1var index = 1;// 开启定时器var timeId = setInterval(function () {// 累加index++;// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在moveUl.style.transition = 'all .3s';// 修改 ul的位置moveUl.style.transform = 'translateX('+index*width*-1+'px)';},1000);// 过渡 结束事件 用来 修正 index的值 并修改索引moveUl.addEventListener('webkitTransitionEnd',function () {console.log('过渡结束');//  如果 index 太大了 if (index>8) {index = 1;// 关闭过渡moveUl.style.transition = '';// 瞬间 修改一下 ul 的位置moveUl.style.transform = 'translateX('+index*width*-1+'px)';}else if(index<1){// 跳到倒数第二张index= 8;// 关闭过渡moveUl.style.transition = '';// 瞬间 修改一下 ul 的位置moveUl.style.transform = 'translateX('+index*width*-1+'px)';}// 修改 索引li标签的 classfor (var i = 0; i < indexLiArr.length; i++) {indexLiArr[i].className = '';}// 有一个 1的 差值indexLiArr[index-1].className = 'current';})

二、手动拨动

1、移动端特有事件:不能通过dom.ontouchstart的方式绑定,只能用addEventListener的方式绑定。

    touchstart:事件参数中有触摸点的值

    touchmove:事件参数中有触摸点的值

    touchend:事件参数中没有触摸点的值

常见的左滑、右滑、长按、捏合等事件都是由touch的这三个事件组合而成。

2、视口属性不能忘:meta:vp+tab


移动端touch事件:

<script type="text/javascript" >window.onload  = function () {// 元素的 事件 绑定时 如果写了 形参 会接受到一个 实参,// 触摸 开始的时候 被触发// 定义 变量 保存 开始的 坐标值var startX = 0;// 定义变量 保存 移动的距离var moveX = 0;// 定义变量 用来 记录 小div 结束的时候 移动的距离var distanceX = 0;// 定义 一堆 记录y方向 移动的 值var startY = 0;var moveY = 0;var distanceY =0;document.body.addEventListener('touchstart',function (event) {console.log('touchstart');// console.log(event);// 获取 起始的 坐标值startX = event.touches[0].clientX;startY = event.touches[0].clientY;console.log('startX:'+startX);})// 手指开始移动时会 一直触发document.body.addEventListener('touchmove',function (event) {console.log('touchmove');// console.log(event);// 这样 就能够获取到 我在X方向移动的距离了moveX = event.touches[0].clientX -startX;console.log('moveX:'+moveX);moveY = event.touches[0].clientY -startY;// 直接 修改 div的 transform// 由于两边 是 字符串拼接 中间是 计算 一定要 加上括号 否则会当 字符串凭借// document.querySelector("div").style.transform = 'translateX('+(moveX+distanceX)+'px)';document.querySelector("div").style.transform = 'translate('+(distanceX+moveX)+'px,'+(distanceY+moveY)+'px)';})// 手指 抬起来的时候 会触发document.body.addEventListener('touchend',function (event) {console.log('touchend');// console.log(event);// 移动 结束的时候 记录 移动的距离// distanceX = moveX +distanceX;distanceX+=moveX;distanceY+=moveY;})}</script>


二、手动轮播:

// 注册 三个 touch事件// 定义变量 记录 开始的Xvar startX = 0;// 记录移动的值var moveX = 0;// 记录 distanceXvar distanceX = 0;// 触摸开始moveUl.addEventListener('touchstart',function (event) {// 关闭定时器clearInterval(timeId);// 关闭过渡效果moveUl.style.transition = '';// 记录开始值startX = event.touches[0].clientX;})// 触摸中moveUl.addEventListener('touchmove',function (event) {// 计算移动的值moveX = event.touches[0].clientX - startX;// 移动ul// 默认的移动值是 index*-1*width moveUl.style.transform = 'translateX('+(moveX+index*-1*width)+'px)';})// 触摸结束/*手指松开的时候 判断 移动的距离 进行 是否吸附由于 不需要考虑 正负 只需要考虑 距离 Math.abs()吸附回的值是 index*-1*width如果移动的距离较大需要判断正负index++;index--; index*-1*width*/moveUl.addEventListener('touchend',function (event) {// 定义 最大的 偏移值var maxDistance = width/3;// 判断 是否超过if (Math.abs(moveX)>maxDistance) {// 判断 到底是 往左 还是往右移动if (moveX>0) {index--;}else{index++;}// 为了好看 将 过渡效果开启moveUl.style.transition = 'all .3s';// 吸附 一整页moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';}else{// 如果 进到这里了 说明 没有超过 我们定义的 最大偏移值 吸附回去即可// 为了好看 将 过渡效果开启moveUl.style.transition = 'all .3s';// 吸附回去moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';}// 记录结束值// 开启定时器timeId = setInterval(function () {// 累加index++;// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在moveUl.style.transition = 'all .3s';// 修改 ul的位置moveUl.style.transform = 'translateX('+index*width*-1+'px)';},1000)})

JS优化:

function banner() {//1 获取变量// 屏幕的宽度var width = document.body.offsetWidth;// console.log(width);\//  获取 轮播图的ulvar moveUl = document.querySelector('.banner_images');// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了// moveUl.style.transition = 'all .3s';// 索引的li标签var indexLiArr = document.querySelectorAll('.banner_index li');// 定义 index 记录 当前的 索引值// 默认 我们的ul 已经 往左边 移动了 一倍的宽度// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1var index = 1;// 抽取的代码 提升代码的可读性,以及 降低维护的难度var startTransition = function () {moveUl.style.transition = 'all .3s';}var endTransition = function () {moveUl.style.transition = '';}// 由于 移动的距离 无法确定 所以提取为参数var setTransform = function (distance) {moveUl.style.transform = 'translateX('+distance+'px)';}// 开启定时器var timeId = setInterval(function () {// 累加index++;// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在// moveUl.style.transition = 'all .3s';startTransition();// 修改 ul的位置// moveUl.style.transform = 'translateX('+index*width*-1+'px)';setTransform(index*width*-1);},1000);// 过渡 结束事件 用来 修正 index的值 并修改索引moveUl.addEventListener('webkitTransitionEnd',function () {console.log('过渡结束');//  如果 index 太大了 if (index>8) {index = 1;// 关闭过渡// moveUl.style.transition = '';endTransition();// 瞬间 修改一下 ul 的位置// moveUl.style.transform = 'translateX('+index*width*-1+'px)';setTransform(index*width*-1);}else if(index<1){// 跳到倒数第二张index= 8;// 关闭过渡// moveUl.style.transition = '';endTransition();// 瞬间 修改一下 ul 的位置// moveUl.style.transform = 'translateX('+index*width*-1+'px)';setTransform(index*width*-1);}// 修改 索引li标签的 classfor (var i = 0; i < indexLiArr.length; i++) {indexLiArr[i].className = '';}// 有一个 1的 差值indexLiArr[index-1].className = 'current';})// 注册 三个 touch事件// 定义变量 记录 开始的Xvar startX = 0;// 记录移动的值var moveX = 0;// 记录 distanceXvar distanceX = 0;// 触摸开始moveUl.addEventListener('touchstart',function (event) {// 关闭定时器clearInterval(timeId);// 关闭过渡效果// moveUl.style.transition = '';endTransition();// 记录开始值startX = event.touches[0].clientX;})// 触摸中moveUl.addEventListener('touchmove',function (event) {// 计算移动的值moveX = event.touches[0].clientX - startX;// 移动ul// 默认的移动值是 index*-1*width // moveUl.style.transform = 'translateX('+(moveX+index*-1*width)+'px)';setTransform(moveX+index*-1*width);})// 触摸结束/*手指松开的时候 判断 移动的距离 进行 是否吸附由于 不需要考虑 正负 只需要考虑 距离 Math.abs()吸附回的值是 index*-1*width如果移动的距离较大需要判断正负index++;index--; index*-1*width*/moveUl.addEventListener('touchend',function (event) {// 定义 最大的 偏移值var maxDistance = width/3;// 判断 是否超过if (Math.abs(moveX)>maxDistance) {// 判断 到底是 往左 还是往右移动if (moveX>0) {index--;}else{index++;}// 为了好看 将 过渡效果开启// moveUl.style.transition = 'all .3s';startTransition();// 吸附 一整页// moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';setTransform(index*-1*width);}else{// 如果 进到这里了 说明 没有超过 我们定义的 最大偏移值 吸附回去即可// 为了好看 将 过渡效果开启// moveUl.style.transition = 'all .3s';startTransition();// 吸附回去// moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';setTransform(index*-1*width);}// 记录结束值// 开启定时器timeId = setInterval(function () {// 累加index++;// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在// moveUl.style.transition = 'all .3s';startTransition();// 修改 ul的位置// moveUl.style.transform = 'translateX('+index*width*-1+'px)';setTransform(index*width*-1);},1000)})}

二、手动拨动(二)


// 页面加载完毕事件window.onload = function () {// 左边的滑动效果left_scroll();}// 左边的滑动效果/*1. 获取一些必须知道的东西移动的dom元素 移动的ul获取 ul父盒子的 高度获取 ul的高度获取移动的 最大值 最小值2.通过touch事件 进行滑动3.手指松开 吸附回去touchend事件吸附回去*/function left_scroll() {// 1获取 必须知道的东西// 获取移动的ulvar moveUl = document.querySelector(".main_left ul");// ul父盒子的高度var parentHeight = document.querySelector(".main_left").offsetHeight;// 获取 header的高度 将下部的偏移值 进行计算var headerHeight = document.querySelector('.header').offsetHeight;// ul的高度var ulHeight = moveUl.offsetHeight;// 计算移动的范围 因为 往上移动个是 y负方向 所有 这里 是减去 而不是加var minDistance = parentHeight - ulHeight - headerHeight;var maxDistance = 0;// 定义变量 用来 标示 吸附的 距离var delayDistance = 150;// console.log('最小值'+minDistance);// console.log('最大值'+maxDistance);// 2.通过touch事件 修改 ul的移动// 定义一些变量 记录 距离//  起始值var startY  = 0;// 移动值var moveY = 0;// 总的移动距离var distanceY = 0// 将 重复的代码 进行封装var startTransition = function () {moveUl.style.transition = 'all .5s';}var endTransition = function () {moveUl.style.transition = '';}var setTransform = function (distance) {moveUl.style.transform = 'translateY('+distance+'px)';}moveUl.addEventListener('touchstart',function(event){startY = event.touches[0].clientY;})moveUl.addEventListener('touchmove',function(event){moveY = event.touches[0].clientY - startY;// 判断 是否满足 移动的条件if ((moveY+distanceY)>(maxDistance+delayDistance)) {// 修正 moveYmoveY = 0;distanceY = maxDistance+delayDistance;// 为什么是减法 因为 往上移动 是负值 要比最小值 还要更小}else if((moveY+distanceY)<(minDistance-delayDistance)){// 修改 moveYmoveY = 0;distanceY = minDistance-delayDistance;}// 关闭 过渡效果// moveUl.style.transition = '';endTransition();// 移动// moveUl.style.transform = 'translateY('+(moveY+distanceY)+'px)';setTransform(moveY+distanceY);})moveUl.addEventListener('touchend',function(event){// 修改移动的总距离distanceY+=moveY;// 吸附回去 判断 吸附的方位if (distanceY>maxDistance) {distanceY = maxDistance;}else if(distanceY<minDistance){distanceY = minDistance;}// 吸附回去// 移动// moveUl.style.transition  ='all .5s';startTransition();// moveUl.style.transform = 'translateY('+(distanceY)+'px)';setTransform(distanceY);})//  第二大部分逻辑  点击 跳转/*逻辑1绑定tap事件绑定给ul即可 事件参数中是能够拿到 触发该事件的 dom元素逻辑2获取 点击的li标签的 索引值让我们的ul 移动 索引值 * li的高度的 距离索引值获取可以再for循环中获取为每一个li 保存一个 索引属性<body  data-index='1'>点击li的时候 获取该属性的值即可dom.dataSet['index'];*/// 在使用之前 先获取// 获取 当前点击的 li标签的 索引值  每一个li标签的 高度var liHeight = document.querySelector('.main_left ul li').offsetHeight;// 用之前 为li标签 绑定一个 data-index 属性// 为所有的li 绑定data-indexvar liArr = document.querySelectorAll('.main_left ul li');// js绑定 自定义属性for (var i = 0; i < liArr.length; i++) {// dataset['index'] 如果 html标签中 已经有了 data-index属性 那么是 赋值操作// 如果 html标签中 没有 data-index属性 那么是 添加该属性的操作liArr[i].dataset['index'] = i;}fox_tap(moveUl,function(e){console.log('触发了tap事件');console.log(e);// 获取的是a标签console.log(e.target);// 获取 a标签的 父盒子 就是 li标签console.log(e.target.parentNode);// 修改 当前点击的 li标签的 class// 清空 所有的for (var i = 0; i < liArr.length; i++) {liArr[i].className = '';}// 高亮当前的 e.target.parentNode.className = 'current';// 知道 当前 点击的li标签的 indexvar currentIndex = e.target.parentNode.dataset['index'];console.log('索引值为:'+currentIndex);// 计算 移动的距离var moveDistance = currentIndex*liHeight*-1;// 对 moveDistance 进行修正if (moveDistance>maxDistance) {// 如果大于最大值,将他 改回来 moveDistance = maxDistance;}else if(moveDistance <minDistance){// 如果 小于最小值 将他 改回 最小值moveDistance = minDistance;}// 开始移动startTransition();// moveDistance 就是一个 符合要求的值setTransform(moveDistance);})}