摘要:每次鼠標移動都是這樣的處理過程,直到鼠標不再移動一秒鐘后,定時器中的函數才被使用。
函數節流的原理
函數節流,就是對會頻繁觸發的函數事件做一些限制,讓這些函數可以在每隔一定的時間或者每次滿足一定的條件下再觸發。一般我們會給他起一個名字throttle。也就是節流的意思。一般這樣的函數有 resize事件、ontouchmove事件等。
舉個簡單的例子
測試函數節流
上面的代碼就是簡單的渲染出來一個div 然后給這個div綁定了一個鼠標移動事件。但是我們在實際情況下,這種體驗是不好的,因為這個事件會被十分頻繁的觸發。只要我們在這個div上移動鼠標就會彈出這個阻塞性的事件alert,所以我們希望每隔一定時間提醒一下“您的鼠標正在移動”。
下面寫一個節流的函數throttle()。
function throttle(func){ var timer; return function(){ var context = this; var args = arguments; clearTimeout(timer); timer = setTimeout(function(){ func.apply(context,args); },1000); } }
然后我們修改一下頁面上的代碼:
測試函數節流
下面我仔細解釋一下這個節流函數。
函數利用閉包的形式存儲了一個timer定時器變量,說實話我剛開始看別人在寫這個節流函數的時候,也是不太容易懂,只是馬馬虎虎覺得是這樣的,直到我親自實現一遍,才明白。在這里建議親自動手,豐衣足食~~
這個timer變量當然也可以寫在全局作用域中,但是可能會跟全局作用域中的變量產生沖突,所以在這里用閉包的形式來提供,防止它污染全局作用域。(看好多人在這里用“污染”,我想可能是如果有很多像timer這樣的變量都放在全局作用域中,到時候肯定容易與在全局作用域中常用的變量混淆。因為它畢竟只是在這個節流函數做定時器使用)。
然后就是throttle函數返回的函數了。在這個函數中,要保存好傳進來的執行上下文this,和參數arguments。應為我們要注意的是setTimeout()函數中作用域是全局的,也就是setTimeout中的this指的是window,在這里這個執行上下文其實就是container對象,傳入的參數就是鼠標移動這個事件的所有信息我們將這個container這個對象的鼠標移動事件函數重寫成alertSomething這個函數。同時鼠標移動事件的信息也作為參數傳入進去這一點也是我打印出他的相應信息后才恍然大悟,可能平時我們會理所當然的知道就是這樣子的,但是為什么會這樣子呢,我們知道了alertSomething這個函數的參數和執行上下文是怎么傳進去的,那直接調用elementobj.onmousemove=function(){xxxxxx}這個函數的時候,上下文和參數是怎么傳入進去的也應該是這樣的原理吧。這是我的個人理解。
明白了上面的基本原理,我們再梳理一下節流函數發揮作用的過程:第一次調用這個節流函數的時候也就是第一次觸發鼠標移動事件的時候,timer是沒有的,所以clearTimeout(timer)清理的定時器也是沒有的,但是等第二次觸發鼠標移動事件的時候,鼠標移動事件的處理函數就是一直是throttle返回的函數了。首先會清理掉上次調用的時候的定時器,然后重新設置一個定時器。每次鼠標移動都是這樣的處理過程,直到鼠標不再移動一秒鐘后,定時器中的函數才被使用。
總之仔仔細細理解一下這個過程感覺真好!
但是如果我們需要自定義延遲的事件的話怎么辦呢,下面我們可以再改進一下:
function throttle(func,delay){ var timer; return function(){ var context = this; var args = arguments; clearTimeout(timer); timer = setTimeout(function(){ func.apply(context,args); },delay); } } function dealMouseMove(){ alert("您的鼠標正在移動"); }; document.getElementById("container").onmousemove = throttle(dealMouseMove,500);在這里感謝 Toobug 和 flowmemo 兩位大神的指正,上面函數的功能更應該稱之為debounce,也即是消除抖動的意思。前端技術中常用的throttle相當于一個頻率控制器,讓一段時間內快速觸發很多次的事件處理程序可以只觸發一定的次數, 而debounce不只是減少了觸發次數,而且要滿足一定的條件下才會觸發。兩者實現方法都是差不多的,叫法不一樣而已,不能將兩者割裂開來。
可以參考的相關網址:http://www.css88.com/archives/4648
可以參考的相關網址:http://www.alloyteam.com/2012/11/javascript-throttle/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79000.html
摘要:后續的一些輔助性優化讀者可以自己琢磨,如函數指向,返回值保存等。 原文:https://keelii.github.io/2016/06/11/javascript-throttle/ 在瀏覽器 DOM 事件里面,有一些事件會隨著用戶的操作不間斷觸發。比如:重新調整瀏覽器窗口大小(resize),瀏覽器頁面滾動(scroll),鼠標移動(mousemove)。也就是說用戶在觸發這些瀏覽...
摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發布第一篇文章,到月日發布最后一篇,感謝各位朋友的收藏點贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發中一些功能點的實現,比如防抖、節流、去重、類型判斷、拷貝、最值、扁平、柯里...
摘要:隆重請出主角防抖與節流。防抖與節流的異同相同都是防止某一時間段內,函數被頻繁調用執行,通過時間頻率控制,減少回調函數執行次數,來實現相關性能優化。參考文章分鐘理解的節流防抖及使用場景函數防抖和節流 showImg(https://segmentfault.com/img/bVburM8?w=800&h=600); 本篇課題,或許早已是爛大街的解讀文章。不過春招系列面試下來,不少伙伴們還...
閱讀 1378·2021-09-26 09:55
閱讀 1917·2019-08-30 12:45
閱讀 1055·2019-08-29 11:20
閱讀 3555·2019-08-26 11:33
閱讀 3412·2019-08-26 10:55
閱讀 1685·2019-08-23 17:54
閱讀 2382·2019-08-23 15:55
閱讀 2341·2019-08-23 14:23