簡體   English   中英

如果再次調用Javascript函數怎么殺?

[英]How to kill a Javascript function if it is called again?

我的網頁上有一個搜索框,其中包含復選框,以便用戶過濾其結果。 一次只能檢查一個復選框。

單擊復選框時,我的代碼將運行並將過濾器應用於列表並返回正確的結果。

我遇到的問題是,當快速連續點擊多次復選框時,它會將請求排隊並逐個拉回。 如果選中復選框然后多次取消選中,則可能需要一段時間。

在Javascript中是否有任何方式通知函數它已被再次調用它應該停止除了最后一個請求之外的所有內容?

你想在你的去抖動函數中包裝onclick回調

http://underscorejs.org/#debounce

說你有這個

function search() {
    // ...
}

$jquery(".myFilterCheckboxes").click(search);

您應該可以將上面的內容更改為:

// Only allow one click event / search every 500ms:
$jquery(".myFilterCheckboxes").click(_.debounce(search, 500));

有大量的去抖動函數,如果你不能或不想包含underscore.js,那么編寫自己的函數並不是什么大問題。

我的第一個想法是去抖動,因為你提到了在短時間內創建多個事件的多次點擊。 去抖動經常用於提前搜索或自動完成等事情,以便在按鍵之間為思考時間提供一點空間。

正如其他人所提到的,在搜索運行時簡單地禁用復選框/單擊事件可能更有意義。 在這種情況下,嘗試這樣的事情:

function disableClick(elem) {
  elem.unbind("click");
  elem.attr("disabled", true);
}

function enableClick(elem, onclick) {
  // Enable click events again
  elem.live("click", search);
  // Enable the checkboxes
  elem.removeAttr("disabled");
}

function search() {
  var boxes = $jquery(".myFilterCheckboxes");
  disableClick(boxes);
  $.get(...).always(function() {
    enableClick(boxes, search);
  });
}

$jquery(".myFilterCheckboxes").live("click", search);

為什么要禁用click事件,將disabled屬性添加到復選框而不僅僅是全局鎖定變量? 好吧,全局鎖可能有些容易出錯,但更重要的是,我們已經有了一個在DOM中很重要的全局對象。 如果我們只是修改DOM狀態,我們會得到正確的行為,並向用戶發出信號,他們應該在復選框上放松,直到搜索完成。

也就是說,使用任何類型的鎖定/解除綁定方案來向用戶指示加載微調器或您正在工作的東西可能是有意義的。

您可以使用鎖定模式:

http://jsfiddle.net/RU6gL/

HTML

<input type="checkbox" onclick="fire()" >CB1
<br />
<input type="checkbox" onclick="fire()" >CB2

JS

function_lock = false

fire = function() {
    // First, check the lock isn't already reserved. If it is, leave immediately.
    if (function_lock) return;

    // We got past the lock check, so immediately lock the function to 
    // stop others entering
    function_lock = true;

    console.log("This message will appear once, until the lock is released")

    // Do your work. I use a simple Timeout. It could be an Ajax call.
    window.setTimeout(function() {
        // When the work finishes (eg Ajax onSuccess), release the lock.
        function_lock = false;
    }, 2000);
}

在此示例中,無論單擊復選框多少次,該函數都只運行一次,直到超時后2秒鍾釋放鎖定為止。

這種模式相當不錯,因為當你釋放鎖定時它會讓你控制opver,而不是依賴像'debounce'這樣的定時間隔。 例如,它將與Ajax一起使用。 如果您的復選框正在觸發Ajax調用以進行過濾,您可以:

  1. 首次單擊時,設置鎖定
  2. 調用Ajax端點。 后續單擊不會調用Ajax端點。
  3. 在Ajax成功函數中,重置鎖定。
  4. 現在可以再次單擊復選框。

HTML

<input type="checkbox" onclick="doAjax()" >CB2

JS

ajax_lock = false

doAjax: function() {
    // Check the lock.
    if (ajax_lock) return;

    // Acquire the lock.
    ajax_lock = true;

    // Do the work.
    $.get("url to ajax endpoint", function() {
         // This is the success function: release the lock
         ajax_lock = false;
    });   
} 

這里的問題是反復單擊該復選框。 您應該在處理時禁用復選框(這也會禁用元素上的單擊事件),然后在完成處理后重新啟用復選框。

去抖是一個好主意,但你並不總是知道你的處理功能需要多長時間才能完成。

這是一個簡單的例子,使用jquery promise在一些處理之后重新啟用復選框http://jsfiddle.net/94coc8sd/

使用以下代碼:

function processStuff() {
    var dfd = $.Deferred();

    // do some processing, when finished, 
    // resolve the deferred object
    window.setTimeout(function(){
        dfd.resolve();
    }, 2000);

    return dfd.promise();
}

function startProcessing() {
    $('#processingCheckbox').attr('disabled', 'disabled');
     var promise = processStuff();    
    promise.done(enableCheckbox);
}

function enableCheckbox() {
    $('#processingCheckbox').removeAttr('disabled');
}

$('#processingCheckbox').on('click', startProcessing);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM