欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談JavaScript函數節(jié)流

 更新時間:2014年12月09日 09:28:34   投稿:hebedich  
這篇文章主要簡單介紹了JavaScript函數節(jié)流的相關知識,有相同需求的小伙伴們可以仔細閱讀下

瀏覽器中某些計算和處理要比其他的昂貴的多。例如,DOM操作比起非DOM交互需要更多的內存和CPU時間。連續(xù)嘗試進行過多的DOM相關操作可能會導致 瀏覽器掛起,有時候甚至會崩潰。尤其在IE中使用onresize事件處理程序的時候容易發(fā)生,當調整瀏覽器大小的時候,該事件連續(xù)觸發(fā)。在 onresize事件處理程序內部如果嘗試進行DOM操作,其高頻率的更改可能會讓瀏覽器崩潰。

     函數節(jié)流背后的基本思想是,某些代碼不可以在沒有間斷的情況連續(xù)重復執(zhí)行。第一次調用函數,創(chuàng)建一個定時器,在指定的時間間隔之后運行代碼。當第二次調用 該函數時,它會清除前一次的定時器并設置另一個。如果前一個定時器已經執(zhí)行過了,這個操作就沒有任何意義。然而,如果前一個定時器尚未執(zhí)行,其實就是將其 替換為一個新的定時器。目的是只有在執(zhí)行函數的請求停止了一段時間之后才執(zhí)行。

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

應用舉例:
     假設有一個<div/>元素需要保持它的高度始終等同于寬度,可作如下編碼:

 function resizeDiv(){
        var div = document.getElementById("mydiv");
        div.style.height = div.offsetWidth + "px";
      }
      window.onresize = function(){
        throttle(resizeDiv);
      }

這里,調整大小的功能被放入了一個叫做resizeDiv的單獨函數中,然后onresize事件處理程序調用throttle()并傳入 resizeDiv函數,而不是直接調用resizeDiv()。多數情況下,用戶是感覺不到變化的,雖然給瀏覽器節(jié)省的計算可能非常大。

下面是其他網友的補充

今天主要寫寫我們平時工作中需要的函數節(jié)流??赡苡械呐笥褜瘮倒?jié)流沒有意識。其實,在工作中,很多場景都需要我們進行js的節(jié)流。最常見的是屏幕伸縮resize,以及touchmove或者scroll等事件的時候。大家不知道有沒有看我之前寫的文章!jquery判斷頁面滾動條上滾下滾,touchmove的滑動方向,大家在使用這些例子的時候,會發(fā)現頁面不停的觸發(fā)touchmove或者scroll因為這里沒有關系到頁面的重繪,因此,我在這里沒有使用javascript函數節(jié)流。但是,當我們使用window.onresize的時候,也會不停的觸發(fā)resize事件!這里就會關系到頁面的重新繪制問題了。因此,在window的resize的時候,我們推薦大家使用函數節(jié)流的方式!

javascript函數節(jié)流簡介
假如你對我上面一大坨文字感到頭大,沒關系,我在這里簡單舉例說明一下函數節(jié)流吧!例如當我們使用

 $(window).resize(function(){
      console.log("haorooms window resize");
    })

會發(fā)現:

這里會輸出好多次。我們簡單的縮小一下窗口,就會不停的觸發(fā)!

這樣在div很多的時候,頁面不停重繪,要是遇到版本比較低的IE等,很可能會出現瀏覽器崩潰的現象!為了避免這種情況,我們可以用函數節(jié)流的方式?;镜乃枷胧牵旱谝淮握{用函數的時候,我們創(chuàng)建一個定時器,在指定時間間隔之后運行代碼,第二次調用的時候,會清楚前一個定時器,并重新設置一個。如果前一個定時器已經執(zhí)行過了,那么這個操作就沒有有意了,如果定時器尚未執(zhí)行,就會將其替換為一個新的定時器。目的是在執(zhí)行函數停止了一段時間之后再執(zhí)行。

用對象的方式可以如下寫:

var haoroomstest={
      timeoutId:null,
      performProcessing:function(){        
          console.log("resize");      

      },
      process:function(){
        clearTimeout(this.timeoutId);
        var that=this;
        this.timeoutId=setTimeout(function(){
          that.performProcessing();
        },500)
      }
    }

這樣之后,我們再用:

$(window).resize(function(){ haoroomstest.process(); })

這樣就會減少請求,減少dom重繪,達到節(jié)流的目的!

函數節(jié)流其他方式
除了我們運用對象的方式,網上及資料中也介紹了關于函數節(jié)流的其他方法和方式,我下面簡單介紹幾種!

函數方式一

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

我們如下使用

function resizeDIv(){
      console.log("haorooms")
    }

    $(window).resize(function(){
      throttle(resizeDIv)
    })

和上面對象實現了同樣的效果!

函數方式二

網上還有一種比較流行的節(jié)流方式,我在這里寫一下!

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

然后可以這么寫:

function resizeDIv(){
      console.log("haorooms")
    }

   window.onresize=throttle(resizeDIv,500);

新需求

我們在做模糊搜索智能聯想提示的時候,會在input上面綁定keyup事件。但是我又不想觸發(fā)的那么頻繁,用上面的方式就會有問題。因此,在上面的函數基礎上稍加改動,如下:

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);
        }
      }
}

這樣觸發(fā)就不會有之前那么頻繁了!

相關文章

最新評論