让你彻底了解什么是节流
題圖 By HymChu From lnstagram
上一篇文章咱們介紹了防抖,這一篇文章大咱們討論一下節(jié)流,同樣咱們看一個需求:頁面中有一個文本框,文本框根據(jù)用戶的輸入,發(fā)送異步請求關聯(lián)數(shù)據(jù),顯示在輸入框下面。
初步實現(xiàn)代碼如下:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title></head><body><input type="text" name="" id="inp"><script>document.querySelector("#inp").oninput = function(){console.log("22222")}</script></body></html>
不考慮性能的話,功能完全能實現(xiàn),但是我們看一下控制臺,input只要一有輸入,就會調(diào)用事件函數(shù),我們發(fā)現(xiàn)這是不必要的,有的朋友可能想到了上一篇文章的防抖,用防抖也可以實現(xiàn)這個功能,但是用防抖的話有一個小問題,那就是等用戶完全輸入停止后才去發(fā)送異步請求。
但是我們需要用戶輸入時候到某個時間節(jié)點,不論用戶有沒有輸入完成都發(fā)送一次異步請求,用戶持續(xù)的輸入,持續(xù)的觸發(fā)input事件,只要到達某事時間間隔,就發(fā)送一次ajax。這樣操作會提升用戶體驗。
按照上面的描述,咱們來思考一下如何實現(xiàn)上面的代碼,首先應該有一個全局變量來獲取當前的時間starttime,然后觸發(fā)input事件的時候,獲取觸發(fā)事件的當前時間currenttime,然后對比兩個時間的時間差,如果插值大于等于規(guī)定的時間間隔timespace,發(fā)送ajax,并且更新starttime,如果小于時間間隔timesapce,不做處理,代碼流程圖如下:
按照流程圖,代碼實現(xiàn)如下:
<script>var starttime = Date.now();var currenttime = null;var timespace = 3000function ajax(){console.log("異步請求,渲染dom")}document.querySelector("#inp").oninput = function(){currenttime = Date.now();if(currenttime-starttime>timespace){ajax()starttime = Date.now();}else{console.log("不做處理")}}</script>
仔細閱讀代碼,發(fā)現(xiàn)代碼又bug,當用戶完全輸入后,反而不會觸發(fā)ajax。所以我們要進行處理,添加一個判斷,判斷用戶輸入完成后,觸發(fā)ajax請求,代碼修改如下:
<script>var starttime = Date.now();var currenttime = null;var timespace = 3000// 添加延時器全局變量var timeout = null;function ajax(){console.log("異步請求,渲染dom")}document.querySelector("#inp").oninput = function(){currenttime = Date.now();if(currenttime-starttime>timespace){clearTimeout(timeout);starttime = Date.now();timeout = null;ajax()}else{// 判斷有無定時器if(!timeout){// 沒有定時器的話,打開定時器timeout = setTimeout(function(){ajax();// 調(diào)用完成后將timeout清空timeout = null;},4000)}}}</script>
這次基本實現(xiàn)了節(jié)流的應用,我們看到節(jié)流一般和防抖結(jié)合使用,因為節(jié)流的最后要判斷用戶是否輸入完成。
上面的代碼依然有好多問題,暴露了多個全局變量,不能復用,更改代碼如下:
<script>function ajax(){console.log("異步請求,渲染dom")}?function throttle(callback){var starttime = Date.now();var currenttime = null;var timespace = 3000var timeout = null;return function(){// 用context和event保存調(diào)用事件的this和事件對象var context = this;var event = arguments[0]currenttime = Date.now();if(currenttime-starttime>timespace){clearTimeout(timeout);starttime = Date.now();timeout = null;// 使callback綁定事件調(diào)用對象,和事件對象callback.call(context,event)}else{// 判斷有無定時器if(!timeout){// 沒有定時器的話,打開定時器timeout = setTimeout(function(){// 使callback綁定事件調(diào)用對象,和事件對象callback.call(context,event)// 調(diào)用完成后將timeout清空timeout = null;},4000)}}}}??document.querySelector("#inp").oninput = throttle(ajax)</script>
我們實現(xiàn)了throttle函數(shù),這個函數(shù)可以將事件的主要邏輯函數(shù)變?yōu)橐粋€節(jié)流函數(shù),并且我們根據(jù)throttle返回的函數(shù)最終調(diào)用者為inputDom,所以用變量context和event保存調(diào)用事件邏輯的this和事件對象,然后將其綁定到callback上面。
針對上面的過程,我們給節(jié)流下一個定義:事件一直觸發(fā),我們獲取事件觸發(fā)時間,比較兩次觸發(fā)時間的間隔,當這個時間間隔達到某個閥值的時候,觸發(fā)事件處理邏輯。
關聯(lián)文章:白話防抖。
以上便是節(jié)流的簡單實現(xiàn),如果你有什么建議或者想法歡迎留言。
歡迎轉(zhuǎn)發(fā)、關注、點擊好看
堅持下去就能成功
總結(jié)
以上是生活随笔為你收集整理的让你彻底了解什么是节流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 理财风险评估即将失效是什么意思?
- 下一篇: 理财被骗法院一直不审怎么办?