每日一kun:你连世界都没观过,哪来的世界观?
怎么说呢,用JS写原生轮播图,代码有点小多,所有加起来大概200行代码,不过该有的东西都有,自动播放,鼠标悬停停止播放,鼠标离开继续播放,还加了个节流阀,防止快速点击上下一页,轮播速度过快。
JS代码
var span = document.querySelectorAll("span")
var div = document.querySelector("div")
var ulRotation = document.querySelector(".rotation")
var ulFlooterLi = document.querySelector(".flooterLi")
var away = ulRotation.children[0].offsetWidth
var num = 0
var liEnd = ulRotation.children[0].cloneNode(true)
var flag = true
for (var i = 0; i < ulRotation.children.length; i++) {
var li = document.createElement("li")
ulFlooterLi.appendChild(li)
li.setAttribute("index", i)
li.addEventListener("click", function () {
for (var i = 0; i < ulFlooterLi.children.length; i++) {
ulFlooterLi.children[i].className = ""
this.className = "current"
packageTimer(ulRotation, -away * (num = this.getAttribute("index")))
}
})
}
ulFlooterLi.children[0].className = "current"
div.addEventListener("mouseenter", function () {
span[0].style.display = "block"
span[1].style.display = "block"
clearInterval(rotationTimer)
})
div.addEventListener("mouseleave", function () {
span[0].style.display = "none"
span[1].style.display = "none"
rotationTimer = setInterval(function () {
span[1].click()
}, 1500)
})
ulRotation.appendChild(liEnd)
span[1].addEventListener("click", function () {
if (flag) {
flag = false
if (num == ulRotation.children.length - 1) {
num = 0
ulRotation.style.left = "0px"
}
num++
packageTimer(ulRotation, -num * away, function () {
flag = true
})
for (var i = 0; i < ulRotation.children.length - 1; i++) {
ulFlooterLi.children[i].className = ""
}
num == ulRotation.children.length - 1 ? ulFlooterLi.children[0].className = "current" : ulFlooterLi.children[num].className = "current"
}
})
span[0].addEventListener("click", function () {
if (flag) {
flag = false
num--
if (num < 0) {
num = ulRotation.children.length - 2
ulRotation.style.left = -(num + 1) * away + "px"
}
packageTimer(ulRotation, -num * away, function () {
flag = true
})
for (var i = 0; i < ulRotation.children.length - 1; i++) {
ulFlooterLi.children[i].className = ""
}
ulFlooterLi.children[num].className = "current"
}
})
var rotationTimer = setInterval(function () {
span[1].click()
}, 1500)
var packageTimer = function (obj, away, comeBack) {
clearInterval(obj.timer)
obj.timer = setInterval(function () {
var step = (away - obj.offsetLeft) / 10
step = step > 0 ? Math.ceil(step) : Math.floor(step)
if (obj.offsetLeft == away) {
clearInterval(obj.timer)
comeBack && comeBack()
}
obj.style.left = obj.offsetLeft + step + "px"
}, 20)
}
HTML代码
<div>
<span class="left">👈</span>
<span class="right">👉</span>
<ul class="rotation">
<li><img src="./image/summer01.jpg"></li>
<li><img src="./image/summer02.jpg"></li>
<li><img src="./image/summer03.jpg"></li>
<li><img src="./image/summer04.jpg"></li>
</ul>
<ul class="flooterLi">
</ul>
</div>
CSSS代码
html {
height: 100%;
}
body {
height: 100%;
}
.left {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.right {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}
div {
width: 720px;
height: 500px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
}
ul li img {
width: 720px;
height: 500px;
}
.flooterLi {
width: 200px;
position: absolute;
bottom: 0px;
left: 50%;
transform: translateX(-50%);
}
.flooterLi li {
float: left;
width: 30px;
list-style-type: disc;
}
.rotation {
list-style: none;
width: 500%;
padding: 0;
float: left;
position: relative;
left: 0px;
z-index: -10;
}
.rotation li {
float: left;
}
span {
display: none;
font-size: 25px;
}
.current {
color: yellowgreen;
width: 30px;
}
效果图

说下几个关键的地方,span[1]这里的span[0]里面的0代表👈,1代表👉,整个轮播图所有元素全部使用百分比定位,这样可以使轮播图永远在屏幕中间,左右箭头永远在上下居中,下面的四个小点,也是靠底居中在轮播图
span[1].addEventListener里面绑定的点击事件所实现的函数写了两个不同的函数,关键点就是点击进来是先Num++,再去完成临界点后面的动作,还是先完成临界点后面的动作,再去Num--,上一页是写完成第一页到最后一页的切换,再实现Num--,调用算法完成换页,下一页反之。
for (var i = 0
ulFlooterLi.children[i].className = ""
}
ulFlooterLi.children[num].className = "current"
上面的代码主要实现4个黑色小点的绿色高亮效果,如果代码看不懂,可以把里面Num单独提取出来var 一个新的变量放进去,因为我这里是直接使用上下一页切换的变量,所以如果你不提取出来那你必须看懂上下页是怎么切换的,再把变量套用到这里。
li.addEventListener("click", function () {
for (var i = 0
ulFlooterLi.children[i].className = ""
this.className = "current"
packageTimer(ulRotation, -away * (num = this.getAttribute("index")))
}
})
这里主要就给Li绑定个点击事件,使用排他思想完成高亮显示,其他代码还好,num = this.getAttribute("index"),就这个有点难度,这里主要是要和翻页代码与小点高亮显示代码一起看,主要就是点击这个小点,把Li上自己定义的一个属性index里面的值取出来,再绑定给Num,这样你点击某个点的时候,代码就知道该显示那张图片与那个点应该高亮显示。
还有个节流阀,节流阀应该是最简单的,就加个IF判断,当翻页代码执行时,开启节流阀,这样在翻页代码执行完毕前,不管点多少次按钮,也不会执行翻页,翻页代码执行完后,使用轮播图核心算法里面的回调函数关闭节流阀,这样就可以继续点击按钮完成翻页。
Tips:Code never lies。