有些浏览器事件会被用户在很短的时间内触发很多次,例如点击事件或滚动页面。如果你给窗口滚动事件添加一个事件监听函数(事件句柄),然后用户不停地快速上下滚动页面,那你的事件可能在一秒之内都会被触发很多次,这会导致严重的性能问题,比如说你的页面卡住了(假死),所以我们需要降低触发回调的频率。
下面就说一下优化这种高频执行js的方法,来提高页面速度和性能。
预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。(设置阈值)
函数防抖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <!DOCTYPE html >
<html >
<head >
<meta charset ="utf-8">
<meta http -equiv ="Content-Security-Policy" content ="upgrade-insecure-requests">
<title >函数防抖 - 打开控制台,滚动你的鼠标小滑轮试试看 </title >
<style >
</style >
</head >
<body style ="height:2000px;">
<h1 >函数防抖 </h1 >
</body >
<script src ="./jquery-2.1.4.min.js"></script>
<script >
var isThrottle = true; //初始化无需走节流
var setTimer = null; //初始化定时器
var throttle = function(fn , time) {
clearInterval (setTimer )
var time = time || 300;
if (isThrottle ) { //注意:在这里第一次滚动时候我们是需要立马执行函数的,真正的防抖是从第二次开始
fn ();
isThrottle = false;
return false;
/*细节:这里如果你不return false阻断代码往下执行,那么在第一次时候实际还会走下面的else,也就是触发了两次,(因为滚轮触发的事件频率很高,第一次节流(else中)的事件会紧接着初始化第一次未节流事件去执行了)*/
} else {
console .log('高频触发滚动事件中')
setTimer = setTimeout (function() {
fn ();
isThrottle = true;
console .log('上一次打印是节流执行。。。')
}, time)
}
}
function conduct () {
console .log("1")
}
$ (document ).scroll (function() {
throttle (conduct , 1000);
})
</script>
</html > |
注意:当你第一次滚动时候,方法不会执行,这当然是属于Bug了,在第一次滚动时候我们应该第一时间执行这个方法,也就是说,真正节流应该是从第二次滚动时候才开始进行,也就是所谓的防抖,它的做法是限制下次函数调用之前必须等待的时间间隔,
如果想处理好真正的节流,很显然,仅仅上面这样处理方式还是不够的,假设用户在mac触摸板下不停的滚动(我也是用mac才发现这个bug)这时候因为每次都会去触发节流函数,但是每次还没执行就被上一个清除定时器给清除了,所以在中途一直不会触发节流,只有每次用户停止才会去触发,很显然不可取,违背了我们的初衷,我们想要的是在第一次立即出发,中间高频率操作过程中间隔一定的时间去更新去出发,而不是必须傻傻的等待用户高频率触发完成后再去触发一次
在线一览
优化封装函数节流方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <!DOCTYPE html >
<html >
<head >
<meta charset ="utf-8">
<meta http -equiv ="Content-Security-Policy" content ="upgrade-insecure-requests">
<title >函数节流、防抖 - 打开控制台,滚动你的鼠标小滑轮试试看 </title >
<style >
body {
background : #fff
}
h1 {
font -size : 24px ;
text -align : center ;
line -height : 36px ;
margin -top : 100px ;
font -weight : normal ;
font -family : "微软雅黑"
}
</style >
</head >
<body style ="height:2000px;">
<h1 >函数节流、防抖 </h1 >
</body >
<script src ="./jquery-2.1.4.min.js"></script>
<script >
function conduct (fn , delay , masExac ) {
var timer ;
var lastTime = new Date();
return function (arg ) {
var now = new Date();
clearTimeout (timer )
if (now - lastTime < masExac ) {
timer = setTimeout (() => {
fn (arg );
lastTime = now ;
}, delay )
} else {
fn (arg );
lastTime = now ;
}
}
}
function Fn (data ){
console .log(data )
}
var throttle = conduct (Fn ,1000,2000)
$ (document ).scroll (function () {
throttle ('1')
})
</script>
</html > |
在线一览
最后解释下节流和防抖区别?节流就是在用户高频度操作时候,让事件不要高频触发,但在中途函数达到多久还没执行时候再去执行一次函数,这个时候用户还在操作过成功,也就是我们上文第二种方式。那么去抖则指的是在用户操作时候,首次触发一次,但在频繁操作过程中不会触发,只会在用户停下来后再去触发一次,也就是上文中的第一种方式。
「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」
共 0 条评论关于"关于js函数节流与函数防抖【完美解决】"
最新评论