JS防抖和节流
JS防抖和节流
-
防抖 (debounce 弟棒死):指触发事件后在n秒内函数只执行一次,若在n秒内再次触发则重新计算
常见应用:搜索、下拉触底加载下一页 -
节流 (throttle 死rua头):连续发生的事件在n秒内只执行一次
防抖
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
#content{
width: 500px;height: 150px;
background-color: beige;
color: #484848;
text-align: center;
font-size: 60px;
font-weight: 600;
line-height: 150px;
}
</style>
<body>
<input id="search" type="text" oninput="count()"/>
<div id="content"></div>
<script>
let num = 1;
let content = document.getElementById("content");
function count(){
content.innerHTML=num++;
}
//触发完毕过两秒执行,重新触发,时间重新计算
function debounce(func,wait){
let timeout;
return function(){
if(timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(function(){
func.apply(this);
},wait)
}
}
content.onmousemove = debounce(count,2000);
// content.onmousemove = count;
</script>
</body>
</html>
防抖方式2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
#content{
width: 500px;height: 150px;
background-color: beige;
color: #484848;
text-align: center;
font-size: 60px;
font-weight: 600;
line-height: 150px;
}
</style>
<body>
<input id="search" type="text" oninput="count()"/>
<div id="content"></div>
<script>
let num = 1;
let content = document.getElementById("content");
function count(){
content.innerHTML=num++;
}
//触发完毕立即执行,过1秒才能再次执行,但1秒内只能执行1次,1秒后再次触发仍只执行一次就要再等1秒
function debounce(func,wait){
let timeout;
return function(){
if(timeout) clearTimeout(timeout)
let callNow = !timeout;
//类型转换,第一次执行没有timeout定时器,timeout为false,!timeout=true,callNow为true
timeout = setTimeout(()=>{
timeout = null;//清空当前定时器句柄
},wait)
if(callNow) func.apply(this);//第一次执行
}
}
content.onmousemove = debounce(count,1000);
</script>
</body>
</html>
节流
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
#content{
width: 500px;height: 150px;
background-color: beige;
color: #484848;
text-align: center;
font-size: 60px;
font-weight: 600;
line-height: 150px;
}
</style>
<body>
<input id="search" type="text" oninput="count()"/>
<div id="content"></div>
<script>
let num = 1;
let content = document.getElementById("content");
function count(){
content.innerHTML=num++;
}
//如果一直触发,每隔1秒执行一次
function throttle(func,wait){
let timeout;
return function(){
if(!timeout){
timeout = setTimeout(()=>{
timeout = null; //清空定时器句柄
func.apply(this); //执行count
},wait)
}
}
}
content.onmousemove = throttle(count,1000);
</script>
</body>
</html>
节流方式2(比方式1更加节省性能)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
#content{
width: 500px;height: 150px;
background-color: beige;
color: #484848;
text-align: center;
font-size: 60px;
font-weight: 600;
line-height: 150px;
}
</style>
<body>
<input id="search" type="text" oninput="count()"/>
<div id="content"></div>
<script>
let num = 1;
let content = document.getElementById("content");
function count(){
content.innerHTML=num++;
}
//通过时间戳方式
function throttle(func,wait){
let prev = 0; //上次记录的时间
return function(){
let now = Date.now(); //当前时间
if(now-prev > wait){ //当前时间-上次时间>等待时间
func.apply(this); //执行函数,发送请求
prev = now; //重置上次记录时间
}
}
}
content.onmousemove = throttle(count,1000);
</script>
</body>
</html>