防抖和节流
1.应用场景:
js的一些事件:如keyup、onresize、scroll、mousemove、mousehover等;还有类似于:手抖、手滑、手误、服务器没有响应或者响应慢等的重复点击操作。
(2019-03-21)优化成下面:
- 防抖:
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源;
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次;
- 防止重复提交;
- 节流:
- 鼠标不断点击触发,mousedown(单位时间内只触发一次);
- 监听滚动事件,比如是否滑到底部加载更多,用throttle来判断。
- 再增加一点:防抖和节流的作用
- 为了减少不必要的计算;
- 不浪费资源;
- 只在适合的时候进行计算。
2.共同点:
均是用来控制某个函数在一定时间内执行多少次的技巧。两种方法都是用来提高前端性能,减轻浏览器压力。
(2019-03-21)优化成下面:
防止某一时间频繁触发事件。
3.区别:
3.1 什么是防抖(debounce)?
延时处理,在事件被触发N秒后再执行回调,如果在这N秒内又被触发,则重新开始计时。
(2019-03-21)增加下面:
- 某一时间段内,只能触发一次,周期内不能再次触发,直到停止后,才可以执行。
window.addEventListener('resize',function(e){
var t;
return function(){
if(t) clearTimeout(t);
t = setTimeout(function(){
// do something...
},500);
}
}());
3.2 什么是节流(throttle)?
让一个函数无法在很短时间内连续调用,当上一次函数过了规定的这个时间段后,才能进行下一次该函数的调用。
(2019-03-21)增加下面:
- 每隔一个周期,执行一次
function throttle(func, waitTime) {
var timeout,
previous = 0;
return function() {
context = this;
args = arguments;
if (!timeout) {
timeout = setTimeout(function(){
timeout = null;
func.apply(context, args)
}, waitTime)
}
}
}
(2019-03-21)防抖和节流实现函数增加下面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>防抖与节流</title>
<style>
#container {
width:400px;
height: 200px;
line-height: 200px;
text-align: center;
color: #ffffff;
background-color: #333;
font-size: 30px;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script>
//防抖和节流的作用: 为了减少不必要的计算,不浪费资源,只在适合的时候进行计算
// var count = 1;
// var container = document.getElementById('container');
// function getUserAction(){
// //大量的算法、逻辑、异步、回调
// console.log(this);
// container.innerHTML = count++;
// }
// container.onmousemove = debounce(getUserAction,1000,true);
// //防抖
// function debounce(func,wait,flag){
// var timeout;
// var self = this;
// return function(){
// clearTimeout(timeout);
// if(flag){//开始边界 就去就是做
// var callnow = !timeout;//callnow:当前状态
// timeout = setTimeout(function(){
// timeout=null;
// },wait);
// if(callnow){
// func.apply(self);
// }
// }else{
// timeout = setTimeout(function(){
// func.apply(self);//为啥this没有代表 <div id="container"></div>?
// },wait);
// }
// }
// }
//可以控制边界
// 开始边界 与 结束边界
// 事件执行一个方法,返回一个方法
//节流
var count = 1;
var container = document.getElementById('container');
function getUserAction(){
//大量的算法、逻辑、异步、回调
container.innerHTML = count++;
}
container.onmousemove = throttle(getUserAction,5000);
function throttle(func,wait){
//用定时器或者时间戳均可以写
var prexious = 0;//用做标记
return function(){
var self = this;
var now = +new Date();//+new Date() 返回13位的时间戳,毫秒数;将会调用Date原型上的valueOf方法,等同于Date原型上的getTime()方法
if(now - prexious > wait){
func.apply(self);
prexious = now;
}
}
}
</script>
</html>
4.文字举例:
A同学从B地到C地,防抖就相当于A同学坐公交车(乘客源源不断的刷卡上车,直到司机看见无人刷卡后,才会发车,即一段时间内,回调函数只会调用一次,即触发事件的最后一次);节流就相当于A同学坐地铁(在规定的停车,在规定的时间发车,即在一段时间内,会每隔一段时间调用一次)。
(2019-03-21)总感觉这段文字解释不太好理解,先划掉吧~
5.结语:
- 听说这是个高频面试题,且先记下。
作者:郑叶叶
出处:http://www.cnblogs.com/zhengyeye
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。