防重複點擊 節流函數


title: 防重複點擊-節流函數 date: 2018-07-09 14:20:58 tags:javascript

  • 前端 categories:
  • 前端

繼續上一內容,更新第二部分,防重複點擊-節流函數的使用。前端

  1. 截圖分享功能

==2. 按鈕防重複點擊(節流函數應用)== 3. 下拉刷新,上拉加載更多(這個地方有坑) 4. 性能優化方面vue

事因:測試小夥伴瘋狂的點擊了分享功能。。。雖然已經作了判斷,屢次點擊只會執行一次分享功能,可是這樣會致使路由變多,後果就是返回時會屢次出現一個頁面。沒辦法只能上節流函數了。java


先作下節流函數的介紹瀏覽器

概念:函數節流是經過一個定時器,阻斷連續重複的函數調用,從而必定程度上優化性能。性能優化

用途:主要用於用戶界面調用的函數,如:resize、mousemove、keyup事件的監聽函數。
這類監聽函數的主要特徵:
一、短期內連續屢次重複觸發;
二、大量的DOM操做。bash

意義:在用戶察覺範圍外,下降函數調用的頻率,從而提高性能async

節流函數原理:函數

某些代碼不能夠在沒有間斷的狀況連續重複執行。第一次調用函數,建立一個定時器,在指定的時間間隔以後運行代碼。當第二次調用該函數時,它會清除前一次的定時器並設置另外一個。若是前一個定時器已經執行過了,這個操做就沒有任何意義。然而,若是前一個定時器還沒有執行,其實就是將其替換爲一個新的定時器。目的是隻有在執行函數的請求中止了一段時間以後才執行。性能

具體用法:

例如:
一、使用onresize
事件處理程序的時候容易發生,當調整瀏覽器大小的時候,該事件會連續觸發。在onresize 事件處理程序內部若是嘗試進行DOM 操做,其高頻率的更改可能會讓瀏覽器崩潰。
二、咱們常見的一個搜索的功能,咱們通常是綁定keyup事件,每按下一次鍵盤就搜索一次。可是咱們的目的主要是每輸入一些內容搜索一次而已。

爲了解決這些問題,就可使用定時器對函數進行節流。

函數代碼以下:

throttle(method, context, params) {
            clearTimeout(method.tId);
            method.tId = setTimeout(function () {
                method.call(context, params);
            }, 200);
        },
複製代碼

在須要使用的地方調用相應的方法,傳入參數:

<a class="news-share" href="javascript:;" @click="clickShare(news)">分享</a>


 clickShare(news) {
            this.throttle(this.handleShare, this, news);
        },

async handleShare(news) {
            console.warn('調用了');
            }
複製代碼

以上爲在vue中的用法。這是一個較爲基礎的節流函數,網上也提供了許多高級一些的節流函數,這個就須要根據各自的項目業務需求進行使用了。

如下內容爲引用:

節流函數加強版:

使用場景:當達到某個時間值時,必定要執行一次這個搜索函數。

<input id="search" type="text" name="search">

function queryData(text){
  console.log("搜索:" + text);
}
var input = document.getElementById("search");
input.addEventListener("keyup", function(event){
  throttle(queryData, null, 500, this.value,1000);
  // throttle(queryData, null, 500, this.value);
  // queryData(this.value);
});

function throttle(fn,context,delay,text,mustApplyTime){
  clearTimeout(fn.timer);
  fn._cur=Date.now();  //記錄當前時間

  if(!fn._start){      //若該函數是第一次調用,則直接設置_start,即開始時間,爲_cur,即此刻的時間
    fn._start=fn._cur;
  }
  if(fn._cur-fn._start>mustApplyTime){
  //當前時間與上一次函數被執行的時間做差,與mustApplyTime比較,若大於,則必須執行一次函數,若小於,則從新設置計時器
     fn.call(context,text);
     fn._start=fn._cur;
  }else{
    fn.timer=setTimeout(function(){
    fn.call(context,text);
    },delay);
  }
}
複製代碼

顯然,連續的輸入,到必定時間間隔以後,queryData函數必然會被調用,可是又不是頻繁的調用。這既達到了節流的目的,又不會影響用戶體驗。

進一步的話,就是能夠在調用throttle函數以前,先對輸入的內容進行判斷,若其值爲空、值不變都不用再調用。

相關文章
相關標籤/搜索