原生JS写淘宝轮播图
ps:整个代码还有逻辑顺序在注释文档里面标注的很清楚了,所以就直接上代码算了,至于演示gif,自己cv大法一下就知道结果了。
- CSS样式部分
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 300px;
padding: 7px;
border: 1px solid #ccc;
margin: 100px auto;
position: relative;
}
.screen {
width: 500px;
height: 300px;
overflow: hidden;
position: relative;
}
.screen li {
width: 500px;
height: 300px;
overflow: hidden;
float: left;
}
.screen ul {
position: absolute;
left: 0px;
top: 0px;
width: 5000px;
}
.all ol {
position: absolute;
right: 10px;
bottom: 10px;
line-height: 20px;
text-align: center;
}
.all ol li {
float: left;
width: 20px;
height: 20px;
background: #fff;
border: 1px solid #ccc;
margin-left: 10px;
cursor: pointer;
}
.all ol li.current {
background: yellow;
}
#arr {
display: none;
z-index: 1000;
}
#arr span {
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #000;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #fff;
opacity: 0.3;
border: 1px solid #fff;
}
#arr #right {
right: 5px;
left: auto;
}
</style>
- body标签部分
<div class="all" id='box'>
<div class="screen" id="screen">
<ul>
<li>
<img src="../1.jpg" width="500" height="300" />
</li>
<li>
<img src="../2.jpg" width="500" height="300" />
</li>
<li>
<img src="../3.jpg" width="500" height="300" />
</li>
<li>
<img src="../4.jpg" width="500" height="300" />
</li>
<li>
<img src="../5.jpg" width="500" height="300" />
</li>
<li>
<img src="../6.jpg" width="500" height="300" />
</li>
<li>
<img src="../7.jpg" width="500" height="300" />
</li>
<li>
<img src="../8.jpg" width="500" height="300" />
</li>
<li>
<img src="../9.jpg" width="500" height="300" />
</li>
</ul>
<ol>
</ol>
</div>
<div id="arr">
<span id="left"><</span>
<span id="right">></span>
</div>
</div>
- script代码部分
//1获取节点
var boxObj = document.getElementById('box');
var screenObj = document.getElementById('screen');
var ulObj = screenObj.firstElementChild;
var lisObj =document.querySelectorAll('#screen>ul>li');
var olObj =screenObj.lastElementChild;
var arrObj = document.getElementById('arr');
var leftObj = document.getElementById('left');
var rightObj = document.getElementById('right');
//获取图片宽度
var imgW = screenObj.offsetWidth;
var times1 = '';//自动轮播定时器的清除符,变量提升
//2根据图片的数量,设置序列号显示
lisObj.forEach(function(v,k){
//console.log(k);//显示图片索引,从0开始 最大索引长度-1
let olLiObj = document.createElement('li');
olLiObj.innerHTML = k+1;
k==0 && (olLiObj.className = 'current');//默认首张选中
olObj.appendChild(olLiObj);
})
//获取一下使用元素追加方式产生的序列号
var olLisObj = olObj.children;
//2-1点击序列号跳转对应图片
//3鼠标移入显示左右点击按钮
boxObj.onmouseover = function(){
arrObj.style.display = 'block';
clearInterval(times1);
}
boxObj.onmouseout = function(){
arrObj.style.display = 'none';
autoPlay()
}
//把第一张克隆一下
let firstImgClone = lisObj[0].cloneNode(true);//为true代表深克隆
ulObj.appendChild(firstImgClone);//把克隆的图片也插入进去
//4点击右边箭头,实现下一张
let imgIndex = 0;
rightObj.onclick = function(){
imgIndex++;
//console.log(imgIndex);
let target = 0;
let execute = false;
if (imgIndex==lisObj.length) {
target = -imgIndex*imgW;
imgIndex = 0;
execute =true;
}else{
target = -imgIndex*imgW;
}
move(ulObj,{left:target},function(){
execute && (ulObj.style.left='0px');
})
sel();
}
//实现上一张
leftObj.onclick = function(){
imgIndex--;
let target = 0;
console.log(imgIndex,'ccc');
//判断边界问题,是否超出第一张
if (imgIndex < 0) {
console.log(imgIndex,'aaa');
//显示克隆的第一张图片
//console.log(-imgW*lisObj.length);
ulObj.style.left = -imgW*lisObj.length+'px';
//
target = -imgW*(lisObj.length-1);
//重新设置最大索引
imgIndex = lisObj.length-1;
}else{
//console.log(111);
target = -imgW*imgIndex;
console.log(imgIndex,'bbbbbb');
}
move(ulObj,{left:target},function(){
})
//显示对应的序列号
sel();
}
//实现下标选中
function sel(){
//获取当前页面选中的并清除
let current = document.querySelector('.current');
current.classList.remove('current');
//并设置让当前的ol下的对应li标签选中
//console.log(olLisObj);
olLisObj[imgIndex].className = 'current';
}
//移动函数
var times = '';
function move(ele, taObj, cb) {
clearInterval(times);
times = setInterval(function () {
// 设置清除定时器的开关
var onOff = false;
// 遍历运动的属性
for (let attr in taObj) {
// console.log(attr);
// 获取元素的实时的运动属性值
let tmpPos = parseInt(getPos(ele, attr));
// 计算speed
let speed = (taObj[attr] - tmpPos) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
// 将运动属性进行更新
ele.style[attr] = tmpPos + speed + 'px';
// console.log(tmpPos + speed, taObj[attr]);
//判断是否达到目标值
if ((tmpPos + speed) == taObj[attr]) {
onOff = true;
}
}
// 判断开关
if (onOff) {
// console.log(times, 222);
clearInterval(times);
// 回调函数存在,就调用
cb && cb();
}
}, 30)
//console.log(times, 111);
}
// 获取元素的实时位置的函数
function getPos(obj, attr) {
if (obj.currentStyle) { // 获取css的样式
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj)[attr]
}
}
//自动播放
function autoPlay(){
times1 = setInterval(()=>{
rightObj.onclick();
},2000)
}
autoPlay();