国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript函數節流概念與用法實例詳解

2019-11-20 09:39:39
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript函數節流概念與用法。分享給大家供大家參考,具體如下:

最近在做網頁的時候有個需求,就是瀏覽器窗口改變的時候需要改一些頁面元素大小,于是乎很自然的想到了window的resize事件,于是乎我是這么寫的

<!DOCTYPE html><html><head>  <title>Throttle</title></head><body>  <script type="text/javascript">    n=0;    function resizehandler(){      console.log(new Date().getTime());      console.log(++n);    }    window.onresize=resizehandler;  </script></body></html>

功能倒是實現了,但是我拖拽的方式改變瀏覽器窗口大小的時候看了下控制臺

沒錯,簡單的一個拖拽讓我的resizeHandler()方法執行了52次,這完全不是我想要的效果,實際上我的resizeHandler()方法的代碼很復雜,甚至會使用ajax向服務器發送請求,要是簡單的一次改變窗口大小就要調用52次這還了得

函數節流

其實我的本意只是窗口resize后頁面做一些調整就可以,而window的resize事件并不是在resize結束后才觸發的,具體則么個頻率我也不知道,但卻是在不停的調用,直到窗口大小不再變化。其實類似的機制還有鼠標的mousemove,都是在短時間內重復觸發。

在《JavaScript高級程序設計》中有專門應對此問題的函數節流

function throttle(method,context){  clearTimeout(method.tId);  method.tId=setTimeout(function(){    method.call(context);  },500);}

原理很簡單,利用定時器,讓函數執行延遲500毫秒,在500毫秒內如果有函數又被調用則刪除上一次調用,這次調用500毫秒后執行,如此往復。這樣我剛才的代碼可以改為

<script type="text/javascript">n=0;function resizehandler(){  console.log(new Date().getTime());  console.log(++n);}function throttle(method,context){  clearTimeout(method.tId);  method.tId=setTimeout(function(){    method.call(context);  },500);}window.onresize=function(){  throttle(resizehandler,window);};</script>

拖拽一下試試,果真只執行了一次

另一種做法

網上還有一種函數節流方案,它是這么做的

function throttle(method,delay){  var timer=null;  return function(){    var context=this, args=arguments;    clearTimeout(timer);    timer=setTimeout(function(){      method.apply(context,args);    },delay);  }}

調用一下試試,一樣的效果

<script type="text/javascript">n=0;function resizehandler(){  console.log(new Date().getTime());  console.log(++n);}function throttle(method,delay){  var timer=null;  return function(){    var context=this, args=arguments;    clearTimeout(timer);    timer=setTimeout(function(){      method.apply(context,args);    },delay);  }}window.onresize=throttle(resizehandler,500);//因為返回函數句柄,不用包裝函數了</script>

比較

兩種方法都是利用了setTimeout,不同的是第二種方法加入的函數延遲執行時間,這個在第一種方案中很容易也具有此功能,加一個參數的事兒。

但第一種方案把tId設為函數的一個變量保存,而第二種創建了一個閉包來存儲。個人覺得差距不大,很喜歡第一種,簡單,高效。

新需求

有一天做了個類似的東西,就像百度首頁輸入自動提示一樣的東西,我在text上綁定keyup事件,每次鍵盤彈起的時候自動提示,但是又不想提示那么頻繁,于是我用了上面方法,但是悲劇了,只有停止輸入等500毫秒才會提示,在輸入過程中根本就沒有提示。看了一下代碼,可不是嘛,只要是用戶會盲打,在500毫秒內按一下鍵盤,提示函數就會不斷被延遲,這樣只有停下來的時候才會提示,這就沒意義了。

能不能在函數節流的基礎上間隔固定時間就執行一次?

小改動

在網上搜了一下我們可以根據第二種寫法(第一種為函數拓展多個變量感覺有些不好)做些改動,添加一個參數作為到固定間隔必須執行

function throttle(method,delay,duration){  var timer=null, begin=new Date();  return function(){    var context=this, args=arguments, current=new Date();;    clearTimeout(timer);    if(current-begin>=duration){       method.apply(context,args);       begin=current;    }else{      timer=setTimeout(function(){        method.apply(context,args);      },delay);    }  }}

這樣每次我們判斷間隔了多久,要是超過設置時間則立即執行一次,以剛才例子試一試效果

window.onresize=throttle(resizehandler,100,200);

果真既沒有頻繁執行也沒有就最后執行

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《JavaScript切換特效與技巧總結》、《JavaScript查找算法技巧總結》、《JavaScript動畫特效與技巧匯總》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 额尔古纳市| 区。| 山阴县| 衡水市| 娄烦县| 壤塘县| 巴东县| 包头市| 康乐县| 平武县| 新沂市| 云龙县| 玉山县| 海晏县| 新密市| 获嘉县| 全州县| 台中县| 余姚市| 水城县| 渭南市| 怀化市| 奉节县| 当涂县| 开封县| 双辽市| 中宁县| 仙桃市| 达拉特旗| 南丰县| 嘉荫县| 阿荣旗| 柳江县| 娄底市| 海晏县| 本溪| 墨玉县| 平乡县| 和龙市| 乐亭县| 西青区|