摘要:節流的實現方式有兩種主流的實現方式,一種是時間戳,一種是設置定時器。使用定時器有個問題就是點擊不會立即執行,需要延遲設定的時間才會執行。
前言
在活動需求中,因為做的狂點小游戲。在實際體驗中就會出現,頻繁的點擊造成動畫的不連貫,影響用戶體驗。并且再播放音效的時候,如果沒點擊一次就觸發一次音效會造成將聲音壓入到棧中,會持續的播放。因此在這里的操作做了節流的限制,隔多少秒觸發一次??偨Y一下節流的實現方法。
節流節流的原理很簡單:如果你持續觸發事件,每隔一段時間,只執行一次事件。
根據首次是否執行以及結束后是否執行,效果有所不同,實現的方式也有所不同。
節流的實現方式有兩種主流的實現方式,一種是時間戳,一種是設置定時器。
本次活動利用的就是該實現方式。
使用時間戳,當觸發事件的時候,我們取出當前的時間戳,然后減去之前的時間戳(最一開始值設為0),如果大于設置的時間周期,就執行函數,然后更新時間戳為當前的時間戳,如果小于就不執行。
具體代碼如下:
function throttle(fun, wait) { var context,args; var previous = 0; return function () { var now = +new Date();//格式化時間 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
如果在事件的回調中執行,就要具體修改一下。這樣寫法適用于,將要執行的函數直接賦值給事件。btn.addEventListener("click",throttle(addSelf,2000),false);因為throttle返回的是一個函數,直接賦值給事件可以觸發執行。
var previous = 0; function throttle(fun, wait) { var context,args; return function () { var now = +new Date();//格式化時間 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
將previous提升到外面,寫法就改為btn.addEventListener("click",function () {
throttle(addSelf,2000)(); },false); 這時throttle函數在后面要加小括號直接執行。使用定時器
當觸發事件的時候,我們設置一個定時器,再觸發事件的時候,如果定時器存在,就不執行,直到定時器執行,然后執行函數,清空定時器,這樣就可以設置下個定時器。
function throttle(fun, wait) { var timeout context,args; return function () { context = this; args = arguments; if(!timeout){ timeout = setTimeout(function () { timeout = null; fun.apply(context,args) },wait) } } }
比較同理如果用在回調函數中,需要將timeout提到函數外面。
使用定時器有個問題就是點擊不會立即執行,需要延遲設定的時間才會執行。
1.第一種事件會立即執行,第二種事件會在n秒后第一次執行
2.第一種事件停止觸發后沒有辦法再執行事件,第二種事件停止觸發后依然會再執行一次事件
結合這兩種方法,并且可以配置是否要第一次立即執行或者停止觸發后再執行一次。直接上代碼
配置第三個參數leading:false表明不需要第一次立即執行。trailing:false表明停止觸發后不再執行最后一次。
var previous = 0; var timeout; function throttle(fun, wait, options) { var context,args; /*var previous = 0;*/ if(!options) options = {}; var later = function () { previous = options.leading === false ? 0 :new Date().getTime(); timeout = null; fun.apply(context,args); if(!timeout) context = args = null; }; var throttled = function () { var now = new Date().getTime(); if(!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if(remaining <= 0 || remaining > wait) { if(timeout){ clearTimeout(timeout); timeout = null; } previous = now; fun.apply(context,args); if(!timeout) context = args = null; } else if(!timeout && options.trailing !==false){ timeout = setTimeout(later,remaining) } }; return throttled; } //使用 btn.addEventListener("click",function () { throttle(addSelf,2000,{trailing:false})(); },false);
注意默認情況下都是兼顧了第一次點擊立即觸發和最后觸發后執行一次。
leading:false和trailing:false不能同時設置。
如果同時設置的話,比如當你在不再點擊的時候,因為trailing設為了false,停止觸發不會設置定時器,所以只要再過了設置的時間,在點擊的話,就會立即執行,就違反了leading:false了。所以該方法只有三種情況可用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90045.html
摘要:函數節流的原理函數節流的原理挺簡單的,估計大家都想到了,那就是定時器。在高級程序設計一書有介紹函數節流,里面封裝了這樣一個函數節流函數,它把定時器存為函數的一個屬性個人的世界觀不喜歡這種寫法。 什么是函數節流? 介紹前,先說下背景。在前端開發中,有時會為頁面綁定resize事件,或者為一個頁面元素綁定拖拽事件(其核心就是綁定mousemove),這種事件有一個特點,就是用戶不必特地搗亂...
摘要:為了解決這些問題,就可以使用定時器對函數進行節流。第一次調用函數,創建一個定時器,在指定的時間間隔之后運行代碼。當第二次調用該函數時,它會清除前一次的定時器并設置另一個。 函數節流的目的 從字面上就可以理解,函數節流就是用來節流函數從而一定程度上優化性能的。例如,DOM 操作比起非DOM 交互需要更多的內存和CPU 時間。連續嘗試進行過多的DOM 相關操作可能會導致瀏覽器掛起,有時候甚...
摘要:目的都是為了降低回調函數執行頻率,節省計算機資源,優化性能,提升用戶體驗。函數防抖事件頻繁觸發的情況下,只有經過足夠的空閑時間,才執行代碼一次。 函數節流和函數防抖的對比分析 一、前言 前端開發中,函數節流(throttle) 和 函數防抖(debounce) 作為常用的性能優化方法,兩者都是用于優化高頻率執行 js 代碼的手段,那具體它們有什么異同點呢?有對這兩個概念不太了解的小伙伴...
摘要:此時需要采用防抖和節流的方式來減少調用頻率,同時不影響原來效果。函數防抖當持續觸發事件時,一段時間段內沒有再觸發事件,事件處理函數才會執行一次,如果設定的時間到來之前就觸發了事件,延時重新開始。 js 防抖 節流 JavaScript 實際工作中,通過監聽某些事件,如scroll事件檢測滾動位置,根據滾動位置顯示返回頂部按鈕;如resize事件,對某些自適應頁面調整DOM的渲染;如ke...
摘要:主要實現思路就是通過定時器,通過設置延時時間,在第一次調用時,創建定時器,寫入需要執行的函數。如果這時前一個定時器暫未執行,則將其替換為新的定時器。 JS中的函數節流 一、什么是函數節流(throttle) 概念:限制一個函數在一定時間內只能執行一次。 舉個栗子,坐火車或地鐵,過安檢的時候,在一定時間(例如10秒)內,只允許一個乘客通過安檢入口,以配合安檢人員完成安檢工作。上例中,每1...
閱讀 3442·2021-11-19 09:40
閱讀 1342·2021-10-11 11:07
閱讀 4871·2021-09-22 15:07
閱讀 2904·2021-09-02 15:15
閱讀 1975·2019-08-30 15:55
閱讀 548·2019-08-30 15:43
閱讀 894·2019-08-30 11:13
閱讀 1462·2019-08-29 15:36