摘要:關于防抖與節(jié)流的應用和解釋自行查找資料。修改如果有定時器就清除如果時間滿足就讓他不滿足總之除了第一次就只讓其中一個執(zhí)行一開始執(zhí)行一次時間戳,最后停止在執(zhí)行一次。
這一篇文章我想寫一下防抖與節(jié)流,因為我自己不是很理解而且說實話,以前知道,但是老忘,雖然概念還有一些簡單的寫法會,但還是缺乏練習和深刻的理解。
當我們不加防抖或節(jié)流的時候就像這樣,鼠標滑過觸發(fā)這么多次,所以我們一個使用防抖或節(jié)流來限制它的請求次數(shù)而不是觸發(fā)次數(shù)。關于防抖與節(jié)流的應用和解釋自行查找資料。
function fn(e) { console.log(this); console.log(e); app.innerHTML = num ++; }
1.防抖
簡單實現(xiàn)
function debounce(fn, delay) { let timer = null; return function(){ clearTimeout(timer); timer = setTimeout(function () { fn(); }, delay); } }
使用節(jié)流后
app.onmousemove = fdebounce(fn, 1000);
我們發(fā)現(xiàn)次數(shù)減少了太多,因為只要你在delay時間內不停地觸發(fā)就不會執(zhí)行直到你的間隔時間大于delay才會執(zhí)行。
我們來看一下this和event。
this是window,event是undefined。
修復this指向和事件參數(shù)
function debounce(fn, delay) { let timer = null, that; return function(e){ that = this; clearTimeout(timer); timer = setTimeout(function () { //this指向window(非嚴格模式) fn.apply(that, [e]); }, delay); } }
或者是
function debounce(fn, delay) { let timer = null; return function(e){ clearTimeout(timer); timer = setTimeout(()=>{ //箭頭函數(shù) fn.apply(this, [e]); }, delay); } }
增強版(是否立即執(zhí)行)
function debounce(fn, delay, immediate) { let timer = null, that; return function (e) { that = this; clearTimeout(timer); if(immediate){ //是否立即執(zhí)行 if(!timer){ // 如果沒有設置定時器就先執(zhí)行 fn.apply(that, [e]); } timer = setTimeout(function () { timer = null;// 設置定時器,使其在delay毫秒內不能執(zhí)行,過了delay毫秒后在執(zhí)行 }, delay); }else{ //否則延時執(zhí)行 timer = setTimeout(function () { fn.apply(that, [e]) }, delay); } }; } //這個if...else只能執(zhí)行一個,要不先執(zhí)行,要不延時執(zhí)行
一開始會執(zhí)行一次,因為錄制不能顯示鼠標所以理解一下。
節(jié)流
簡易版(時間戳)
function throttle(fn, delay) { let last = 0, //上次執(zhí)行時間 now; //執(zhí)行時的時間 return function (e) { now = Date.now(); //當前時間 if(now - last >= delay){ //如果兩次時間間隔大于delay,就執(zhí)行 last = now; //重新賦值 fn(); } }; }
在規(guī)定時間delay毫秒內總會執(zhí)行一次事件。
setTimeout版本(修復this指向和事件參數(shù))
function throttle(fn, delay) { let that, timer = null; return function (e) { that = this; if(!timer){ //如果沒設置定時器就執(zhí)行 timer = setTimeout(function () { fn.apply(that, [e]); timer = null; //果delay毫秒就設置timer,這樣就能delay執(zhí)行一次 }, delay); } }; }
修復this指向和事件參數(shù)(時間戳)
function throttle(fn, delay) { let last = 0, //上次執(zhí)行時間 now; //執(zhí)行時的時間 return function (e) { now = Date.now(); //當前時間 if(now - last >= delay){ //如果兩次時間間隔大于delay,就執(zhí)行 last = now; //重新賦值 fn.apply(this, [e]); } }; }
區(qū)別
時間戳版本的會先執(zhí)行
setTimeout版本的會后執(zhí)行
所以可以結合一下他們兩個。
結合版
function throttle(fn, delay) { let last = 0, //上次執(zhí)行時間 now, //當前時間 leftTime, //剩余時間 that, timer = null; return function (e) { that = this; now = Date.now(); leftTime = delay - (now - last); if(leftTime <= 0){ //保證一開始就執(zhí)行(先執(zhí)行) last = now; fn.apply(that, [e]); }else{ timer = setTimeout(function() { //延時執(zhí)行 fn.apply(that, [e]); timer = null; },delay) } }; }
這樣做總體思路沒錯,但是第一次會執(zhí)行以后就是兩個一起執(zhí)行,因為條件都滿足。
修改
function throttle(fn, delay) { let last = 0, now, leftTime, that, timer = null; return function (e) { that = this; now = Date.now(); leftTime = delay - (now - last); if(leftTime <= 0){ if(timer){ //如果有定時器就清除 clearTimeout(timer); timer = null; } last = now; fn.apply(that, [e]); }else if(!timer){ timer = setTimeout(function() { last = now; //如果時間滿足就讓他不滿足 //總之除了第一次就只讓其中一個執(zhí)行 fn.apply(that, [e]); timer = null; },delay) } }; }
一開始執(zhí)行一次(時間戳),最后停止在執(zhí)行一次(setTimeOut)。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/101084.html
摘要:文章來源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會碰到一些會持...
摘要:文章來源詳談防抖和節(jié)流輕松理解函數(shù)節(jié)流和函數(shù)防抖函數(shù)防抖和節(jié)流好啦,今天的小菊花課堂之的防抖與節(jié)流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發(fā)中,我們經(jīng)常會碰到一些會持...
摘要:對象是無法通過這種方式深拷貝。這就是函數(shù)防抖和節(jié)流要做的事情。函數(shù)防抖當觸發(fā)頻率過高時函數(shù)基本停止執(zhí)行而函數(shù)節(jié)流則是按照一定的頻率執(zhí)行事件。 對象的深淺拷貝 對象的深拷貝與淺拷貝的區(qū)別: 淺拷貝:僅僅復制對象的引用, 而不是對象本身。 深拷貝:把復制的對象所引用的全部對象都復制一遍 淺拷貝的實現(xiàn): var obj = { age : 18, person : { ...
摘要:封裝方法也比較簡單,書中對此問題也進行了處理使用定時器,讓函數(shù)延遲秒后執(zhí)行,在此秒內,然后函數(shù)再次被調用,則刪除上次的定時器,取消上次調用的隊列任務,重新設置定時器。 在實際開發(fā)中,函數(shù)一定是最實用最頻繁的一部分,無論是以函數(shù)為核心的函數(shù)式編程,還是更多人選擇的面向對象式的編程,都會有函數(shù)的身影,所以對函數(shù)進行深入的研究是非常有必要的。 函數(shù)節(jié)流 比較直白的說,函數(shù)節(jié)流就是強制規(guī)定一...
摘要:函數(shù)節(jié)流保證如果電梯第一個人進來后,秒后準時運送一次,這個時間從第一個人上電梯開始計時,不等待,如果沒有人,則不運行。 前言 有一些瀏覽器事件我們不希望它很頻繁的觸發(fā),如調整窗口大小(onresize)、監(jiān)聽滾動條滾動(onscroll),如果這些監(jiān)聽事件需要調用接口的話一秒內可能會調用上百次,這樣坑定是有問題的。 函數(shù)防抖(debounce) 如果有人進電梯(觸發(fā)事件),那電梯將在1...
閱讀 797·2021-11-11 16:54
閱讀 1533·2021-08-24 10:01
閱讀 1922·2019-08-30 15:54
閱讀 3303·2019-08-29 14:02
閱讀 3138·2019-08-28 18:22
閱讀 2253·2019-08-28 18:09
閱讀 3715·2019-08-26 10:26
閱讀 2674·2019-08-23 18:23