直接進入正題开镣,有的時候使用scroll或者mousemove這類函數(shù)并不需要那么頻繁的調用這些函數(shù),舉個栗子咽扇,dom的mousemove 事件邪财。
<div id="content"
style="height:800px;width:800px;line-height:400px;text-align:center; color: rgb(0, 0, 0);background-color:rgb(134, 70, 70);font-size:80px;font-weight: 800;"></div>
<script>
let num = 1;
let content = document.getElementById('content');
content.onmousemove = ()=>{
content.innerHTML = num++;
};
</script>
mark
在有些業(yè)務下顯然是不合理的,比如監(jiān)聽訪問后的網(wǎng)絡請求质欲, 只要請求速度跟不上響應的速度树埠,那么肯定會有卡頓的情況發(fā)生,以下有幾種解決辦法
防抖(debounce)
多次訪問函數(shù)嘶伟,最終變成一次執(zhí)行的方式
1.通過不斷重置setTimeout的時間來讓方法延遲執(zhí)行弥奸,show code follow
mark
let num = 1;
let content = document.getElementById('content');
function move() {
content.innerHTML = num++;
}
content.onmousemove = debounce(move, 1000)
//第一次訪問設置1000的timeout,以后每次訪問都是由apply來引導到當前this的函數(shù)(也就是debounce)重置timeout
function debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
解釋在注釋奋早,業(yè)務中當鼠標停住后盛霎,最后一次延時計時1000ms赠橙,然后move()
節(jié)流(throttle )
1.對比前后兩次的時間戳,間隔很小取消執(zhí)行愤炸,間距很大即可執(zhí)行期揪,show code follow
mark
let num = 1;
let content = document.getElementById('content');
function move() {
content.innerHTML = num++;
}
content.onmousemove = throttle(move, 1000)
function throttle(func, wait) {
var context, args;
var previous = 0;
return function() {
var now = +new Date();
context = this;
args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
2.setTimeout定時器也可以達到效果相同的節(jié)流效果,show code follow
mark
let num = 1;
let content = document.getElementById('content');
function move() {
content.innerHTML = num++;
}
content.onmousemove = throttle(move, 1000)
function throttle1(func, wait) {
var timeout;
var previous = 0;
return function () {
context = this;
args = arguments;
if (!timeout) {
timeout = setTimeout(function () {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
但是這兩種節(jié)流的實現(xiàn)方法還是有很大區(qū)別的
一规个、
第一種對比時間戳是一旦滿足空擋時間即刻執(zhí)行凤薛,
第二種是定時器控制定時完成后再去執(zhí)行函數(shù),有本質上的區(qū)別
PS:假如空隙為3s诞仓,第一種會立即執(zhí)行第一次缤苫,第二種會3s后執(zhí)行第一次、
二墅拭、
一種事件停止觸發(fā)后沒有辦法再執(zhí)行事件活玲,第二種事件停止觸發(fā)后依然會再執(zhí)行一次事件
附上原文鏈接,歡迎大家討論
https://github.com/mqyqingfeng/Blog/issues/22