这是我参与更文挑战的第21天,活动详情查看: 更文挑战
什么是节流?
想必大家对一个成员是不陌生的:开源节流,那么节流函数为什么叫节流呢?
因为流量太大了,所以控制一下,隔一段时间放一些,隔一段时间放一些,就节流了。
所以节流函数,就是隔一段时间执行一次,否则的话,就拒绝执行,节省开支。
节省开支这一点,也是节流函数在性能优化中,很重要的存在依据,毕竟性能优化的前提就是节能性能消耗的同时,不影响用户体验。
所以赶快学起来吧。
通用简单版
function throttle(func, wait) {
var _this, args;
var previous = 0;
return function() {
var now = +new Date();
_this = this;
args = arguments;
if (now - previous > wait) {
func.apply(_this, args);
previous = now;
}
}
}
设置一个默认时间戳值为0, 当触发节流函数的时候,获取一个当前时间的时间戳,并减去前一个时间戳(默认时间),如果大于设置的等待时间,则立即执行函数, 并重置默认时间戳。
这样就达到了每隔一段时间就执行一次的效果了。
该方法会在触发后立即执行一次,停止触发则不只执行最近一次
定时器版
function throttle(func, wait) {
var timeout;
var previous = 0;
return function() {
_this = this;
args = arguments;
if (!timeout) {
timeout = setTimeout(function(){
timeout = null;
func.apply(_this, args)
}, wait)
}
}
}
触发事件时,判断定时器是否存在,如果存在的话就不执行,直到定时器自己执行,并清空自己。
否则的话,就设置一个延时定时器,等待函数执行。
并不会立即执行,但停止触发也会执行最近一次的调用
结合:有头有尾
function throttle(func, wait) {
var timeout, _this, args, result;
var previous = 0;
var later = function() {
previous = +new Date();
timeout = null;
func.apply(_this, args)
};
var throttled = function() {
var now = +new Date();
//下次触发 func 剩余的时间
var remaining = wait - (now - previous);
_this = this;
args = arguments;
// 如果没有剩余的时间或者修改了系统时间
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(_this, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
};
return throttled;
}
结合了前两种方法,在调用时,直接执行一次,停止触发也会执行最后一次。
算是有头有尾了。
总结
录制GIF的软件的死活装不上去,所以没法录制效果图了,需要用到的小伙伴可以自己建个html,写个demo测试下。
这里给个demo的模板
<body>
<div id="wrap" style="width: 100px; height: 100px;"></div>
</body>
<script>
let wrap = document.getElementById('wrap'),
count = 1;
function fn(){ console.log(1); }
// throttle
wrap.onmousemove = throttle(fn, 1000);
</script>