我有一个表,可以使用向上/向下箭头选择行,并且当选择行时,该行将关闭并通过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并创建一个名为blahblah的新反跳包装器,只能使用一次。

每个击键动作都会调用一次这些去抖器,因此没有真正被去抖,并且所有操作都会延迟250毫秒。

您应该在blahblah之外定义someFunction,这样可以解决您的计时问题。不要忘记将事件对象传递给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);
}


同样,还有其他问题,但是上面的解决方案应该已经解决了。为了完整起见,我想指出这一点。 someFunction在OP中的编写方式,存在名称遮盖问题。让我们重命名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

09-25 16:43