从keydown事件侦听器

时间:2016-06-25 06:47:23

标签: javascript jquery angularjs 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();
}

1 个答案:

答案 0 :(得分:3)

看起来每次按下keydown时,都会调用someFunction并创建一个名为blahblah 的新debounced包装器,只能使用一次。

这些去抖动中的每一个都会在每次击打时被调用一次,因此没有任何真正的去抖动,并且一切都会延迟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);
}

此外,还有一个问题,但上面的解决方案应该照顾它。为了完整起见,我想指出来。在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