簡體   English   中英

從keydown事件偵聽器中提取防抖動功能

[英]Extracting a debounce function from a keydown event listener

我有一個表,可以使用向上/向下箭頭選擇行,並且當選擇行時,該行將關閉並通過ajax獲取記錄。

為了阻止用戶向ajax請求發送垃圾郵件,我有一個反跳功能,該功能是我從指令中調用的。 這是通過keydown事件觸發的。 所有這些都有效,但不是我需要的方式。 我希望在調用防抖動功能之前調用preventDefault。 因此,用戶仍然可以在沒有延遲的情況下向上/向下移動行,而ajax仍然僅在延遲之后才觸發。

我認為我需要將我的代碼提取出來,以允許這樣做,但是嘗試了幾件事之后,我無法使其正常運行。 這是原始版本:

在指令中:

$('table').keydown(scope.debounce(function (e) {

    if(e.keyCode == 38) { // Up arrow
        // Do Ajax stuff

        e.preventDefault();
        e.stopPropagation();
    }

    if(e.keyCode == 40) { // Down arrow
        // Do Ajax stuff

        e.preventDefault();
        e.stopPropagation();
    }

}, 250));

在控制器中:

$scope.debounce = function (fn, delay) {
    var timer = null;

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

我嘗試提取在keydown上調用的函數,但現在它只是在忽略延遲。 我無法理解如何使其工作。 這是我到目前為止的內容:

在控制器中:

$('table').keydown(someFunction);

function someFunction(e) {
    e.preventDefault();
    e.stopPropagation();

    var blahblah = scope.debounce(function (e) {

        if(e.keyCode == 38) { // Up arrow
            // Do Ajax stuff
        }

        if(e.keyCode == 40) { // Down arrow
            // Do Ajax stuff
        }

    }, 250);

    blahblah();
}

看起來每次按下keydown時, someFunction調用someFunction並創建一個名為blahblah的新的反跳包裝器,只能使用一次。

每個擊鍵動作都會調用一次這些去抖器,因此沒有真正被去抖,並且所有操作都會延遲250毫秒。

您應該在someFunction之外定義blahblah ,這樣可以解決您的計時問題。 不要忘記將事件對象傳遞給blahblah

$('table').keydown(someFunction);

var blahblah = scope.debounce(function (e) {

    if(e.keyCode == 38) { // Up arrow
        // Do Ajax stuff
    }

    if(e.keyCode == 40) { // Down arrow
        // Do Ajax stuff
    }
}, 250);

function someFunction(e) {
    e.preventDefault();
    e.stopPropagation();

    blahblah(e);
}

同樣,還有其他問題,但是上面的解決方案應該已經解決了。 為了完整起見,我想指出這一點。 在OP中編寫someFunction的方式,您會遇到名稱隱藏問題。 讓我們重命名blahblah的參數e來說明這一點:

var blahblah = scope.debounce(function (innerE) {

    if(innerE.keyCode == 38) { // Up arrow
        // Do Ajax stuff
    }

    if(innerE.keyCode == 40) { // Down arrow
        // Do Ajax stuff
    }

}, 250);

因此,當您隨后調用blahblah()而不傳遞事件對象時, innerE是未定義的。 這不是外部作用域的事件對象e

暫無
暫無

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

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