原生JavaScript轮播图的节流
js的防抖与节流
防抖(debounce)
在函数需要频繁触发时,只有当有足够空闲的时间时,才执行一次。就好像在百度搜索时,每次输入之后都有联想词弹出,这个控制联想词的方法就不可能是输入框内容一改变就触发的,他一定是当你结束输入一段时间之后才会触发。
节流(thorttle)
预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。
区别
在发生持续触发事件时,防抖设置事件延迟并在空闲时间去触发事件,而节流则是隔一定的时间触发一次。
原生JavaScript轮播图的节流
原生JavaScript轮播图的节流是为了防止轮播图在不断的点击的操作下,造成内容跑飞与错位的情况。
CSS部分
.lunbo {
/* slideshow */
width: 202px;
height: 188px;
margin: 100px auto;
background-color: hotpink;
}
.box {
/* slideshow的主窗口 */
border: 1px solid black;
width: 200px;
height: 186px;
position: relative;
}
ul {
/* 所有图片的列表 */
margin: 0;
padding: 0;
list-style: none;
position: absolute;
}
li {
/* 内含img */
float: left;
}
button {
/* 滑动按钮 */
margin: 0;
padding: 0;
text-align: center;
width: 40px;
height: 20px;
line-height: 20px;
font-size: 16px;
border-radius: 5px;
}
.btnL {
/* left按钮 */
position: absolute;
top: 83px;
left: 0;
}
.btnR {
/* right按钮 */
position: absolute;
top: 83px;
right: 0;
}
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./effect.css">
</head>
<body>
<div class="lunbo">
<div class="box">
<ul>
<li><img src="./image/01.jpg" alt=""></li>
<li><img src="./image/02.jpg" alt=""></li>
<li><img src="./image/03.jpg" alt=""></li>
<li><img src="./image/04.jpg" alt=""></li>
<li><img src="./image/05.jpg" alt=""></li>
<li><img src="./image/06.jpg" alt=""></li>
</ul>
<button class="btnL">left</button>
<button class="btnR">right</button>
</div>
</div>
<script src="./slideshow.js">
</script>
</body>
</html>
JS部分 节流
var btnL = document.getElementsByClassName("btnL")[0];
var btnR = document.getElementsByClassName("btnR")[0];
var box = document.getElementsByClassName("box")[0];
var ul = document.getElementsByTagName("ul")[0];
var liArr = document.getElementsByTagName("li");
// bool为节流设置开关
var bool = true;
// 将ul的width设置为显示窗口的width*li的数量
ul.style.width = liArr.length * box.offsetWidth + "px"
// 为显示窗口设置溢出隐藏
box.style.overflow = "hidden"
// 合理的显示或隐藏按钮
box.onmouseenter = function() {
btnL.style.display = "block"
btnR.style.display = "block"
};
box.onmouseleave = function() {
btnL.style.display = "none"
btnR.style.display = "none"
};
// 为了整体美观将li限制为显示区域的大小
for (var i; i < liArr.length; i++) {
liArr[i].style.width = box.offsetWidth + "px"
}
btnL.onclick = function() {
if (ul.offsetLeft < 0) {
// 节流的关键在于一个函数只有在大于等于执行周期时才执行,周期内调用不执行.
// 利用开关 在函数执行时关闭再次执行的开关,在函数执行结束的回调中再次开启开关
if (bool) {
bool = false
move(ul, ul.offsetLeft + 200, function fn() {
bool = true
})
// move 是封装的简易缓动框架
}
}
};
btnR.onclick = function() {
if (ul.offsetLeft < ul.offsetWidth)
if (bool) {
bool = false
move(ul, ul.offsetLeft - 200, function fn() {
bool = true
})
}
}
// 简易缓动框架
function move(dom, left, fn) {
// 优化写法先清除dom身上的定时器
// 在有节流的情况下可以不写
clearInterval(dom.timer);
dom.timer = setInterval(function() {
// 获取dom此时所处的位置信息
var css = parseInt(window.getComputedStyle(dom, null).left)
// 设置步长
var need = (left - css) / 10;
need = need > 0 ? Math.ceil(need) : Math.floor(need);
// 判断是继续执行还是结束定时器
if (Math.abs(left - css) <= Math.abs(need)) {
// 闪现到目标位置
dom.style.left = left + "px"
clearInterval(dom.timer);
if (fn) {
fn()
}
} else {
// 缓动中
dom.style.left = css + need + "px"
}
}, 100)
}
以上纯属个人看法,如有错误,欢迎大家指出。







浙公网安备 33010602011771号