话不多说直接上代码。
【原生JS实现移动端轮播图。】html 结构
css样式
.jd_banner{
width: 100%;
overflow: hidden;
position: relative;
}
/*.jd_bannerImg{
width:800%;
}*/
.jd_bannerImg{
width:800%;
/*position: absolute;
如果使用absolute定位,会造成父容器无法获取由子元素的撑开的高度*/
position: relative;
/*添加默认偏移*/
/*transform: translateX(-10%);
*/
/*使用定位:使用百分比的时候是参照父容器的宽度*/
/* left: -100%;
*/
}
/*.jd_bannerImg > li{
width:12.5%;
float: left;
}*/
.jd_bannerImg > li{
width:12.5%;
float: left;
}
.jd_bannerImg > li img{
/*1.设置为块元素
2.可以将文本的字体大小设置为0
3.vertical-align:bottom*/
display: block;
width: 100%;
}
.jd_bannerIndicator{
width: 128px;
height: 10px;
position: absolute;
left: 50%;
bottom: 5px;
transform: translateX(-50%);
}
.jd_bannerIndicator > li{
width: 6px;
height: 6px;
border-radius: 3px;
border: 1px solid #fff;
float: left;
margin-left:10px;
}
.jd_bannerIndicator > li:first-of-type{
margin-left:0;
}
.jd_bannerIndicator > li.active{
background-color: #fff;
}
js
1.设置一下轮播的页面结构,以及获取一下需要用到的元素。
/*获取轮播图结构*/
var banner=document.querySelector(".jd_banner");
/*获取图片容器*/
var imgBox=banner.querySelector("ul:first-of-type");
/*获取原始的第一张图片*/
var first=imgBox.querySelector("li:first-of-type");
/*获取原始的最后一张图片*/
var last=imgBox.querySelector("li:last-of-type");
/*在首尾插入两张图片cloneNode:复制一个dom元素*/
imgBox.appendChild(first.cloneNode(true));
/*insertBefore(需要插入的dom元素,位置)*/
imgBox.insertBefore(last.cloneNode(true),imgBox.firstChild);
/*获取所有图片li元素*/
var lis=imgBox.querySelectorAll("li");
/*获取li元素的数量*/
var count=lis.length;
/*.获取banner的宽度*/
var bannerWidth=banner.offsetWidth;
/*设置图片盒子的宽度*/
imgBox.style.width=count*bannerWidth+"px";
/*设置每一个li(图片)元素的宽度*/
for(var i=0;
i
2.实现自动轮播
var timerId;
var startTime=function(){
timerId=setInterval(function(){
index++;
imgBox.style.transition="left 0.5s ease-in-out";
/*5.3 设置偏移*/
imgBox.style.left=(-index*bannerWidth)+"px";
/*5.4 判断是否到最后一张,如果是则回到索引1的位置*/
setTimeout(function(){
if(index==count-1){
index=1;
imgBox.style.transition="none";
/*偏移到指定的位置*/
imgBox.style.left=(-index*bannerWidth)+"px";
indicators[count - 3].classList.remove('active');
indicators[0].classList.add('active');
}
},500);
},1000);
}
startTime();
3.实现点标记
var indicators=banner.querySelector("ul:last-of-type").querySelectorAll("li");
var setIndicator=function(index){
/*先清除其它li元素的active样式*/
for(var i=0;
i
4.实现手动轮播
var startX,moveX,distanceX;
/*标记当前过渡效果是否已经执行完毕*/
var isEnd=true;
/*为图片添加触摸事件--触摸开始*/
imgBox.addEventListener("touchstart",function(e){
clearInterval(timerId);
/*获取当前手指的起始位置*/
startX= e.targetTouches[0].clientX;
});
/*为图片添加触摸事件--滑动过程*/
imgBox.addEventListener("touchmove",function(e){
if(isEnd==true){
/*记录手指在滑动过程中的位置*/
moveX= e.targetTouches[0].clientX;
distanceX=moveX-startX;
/*为了保证效果正常,将之前可能添加的过渡样式清除*/
imgBox.style.transition="none";
/* 本次的滑动操作应该基于之前轮播图已经偏移的距离*/
imgBox.style.left=(-index*bannerWidth + distanceX)+"px";
}
});
/*添加触摸结束事件*/
imgBox.addEventListener("touchend",function(e){
/*松开手指,标记当前过渡效果正在执行*/
isEnd=false;
/*获取当前滑动的距离,判断距离是否超出指定的范围 100px*/
if(Math.abs(distanceX) > 100){
/*判断滑动的方向*/
if(distanceX > 0){//上一张
index--;
}
else{ //下一张
index++;
}
/*翻页*/
imgBox.style.transition="left 0.5s ease-in-out";
imgBox.style.left=-index*bannerWidth+"px";
}
else if(Math.abs(distanceX) > 0){ //得保证用户确实进行过滑动操作
/*回弹*/
imgBox.style.transition="left 0.5s ease-in-out";
imgBox.style.left=-index*bannerWidth+"px";
}
/*将上一次move所产生的数据重置为0*/
startX=0;
moveX=0;
distanceX=0;
});
/*webkitTransitionEnd:可以监听当前元素的过渡效果执行完毕,当一个元素的过渡效果执行完毕的时候,会触发这个事件*/
imgBox.addEventListener("webkitTransitionEnd",function(){
console.log("webkitTransitionEnd");
/*如果到了最后一张(count-1),回到索引1*/
/*如果到了第一张(0),回到索引count-2*/
if(index==count-1){
index=1;
imgBox.style.transition="none";
imgBox.style.left=-index*bannerWidth+"px";
}
else if(index==0){
index=count-2;
imgBox.style.transition="none";
imgBox.style.left=-index*bannerWidth+"px";
}
/*设置标记*/
setIndicator(index);
setTimeout(function(){
isEnd=true;
clearInterval(timerId);
startTime();
},100);
});
推荐阅读
- react|react-native支付宝,微信支付对接接口
- 微信小程序 异步阻塞(Promise、resolve,await,then)
- 前端|Taro安装步骤
- 1px问题|vue解决移动端1px边框的问题 border.css
- 仿京东移动端手指拨动切换轮播图效果
- 移动端|移动端 touch事件 过渡事件 动画事件