一、自动轮播
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);\
// 获取 轮播图的ul
var moveUl = document.querySelector('.banner_images');
// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了
// moveUl.style.transition = 'all .3s';
// 索引的li标签
var indexLiArr = document.querySelectorAll('.banner_index li');
// 定义 index 记录 当前的 索引值
// 默认 我们的ul 已经 往左边 移动了 一倍的宽度
// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1
var 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标签的 class
for (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事件
// 定义变量 记录 开始的X
var startX = 0;
// 记录移动的值
var moveX = 0;
// 记录 distanceX
var 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);\
// 获取 轮播图的ul
var moveUl = document.querySelector('.banner_images');
// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了
// moveUl.style.transition = 'all .3s';
// 索引的li标签
var indexLiArr = document.querySelectorAll('.banner_index li');
// 定义 index 记录 当前的 索引值
// 默认 我们的ul 已经 往左边 移动了 一倍的宽度
// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1
var 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标签的 class
for (var i = 0; i < indexLiArr.length; i++) {
indexLiArr[i].className = '';
}
// 有一个 1的 差值
indexLiArr[index-1].className = 'current';
})
// 注册 三个 touch事件
// 定义变量 记录 开始的X
var startX = 0;
// 记录移动的值
var moveX = 0;
// 记录 distanceX
var 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获取 必须知道的东西
// 获取移动的ul
var 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)) {
// 修正 moveY
moveY = 0;
distanceY = maxDistance+delayDistance;
// 为什么是减法 因为 往上移动 是负值 要比最小值 还要更小
}else if((moveY+distanceY)<(minDistance-delayDistance)){
// 修改 moveY
moveY = 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-index
var 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标签的 index
var 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);
})
}