javascript - 从 keydown 事件监听器中提取去抖函数

标签 javascript jquery angularjs ajax

我有一个表,可以使用向上/向下箭头选择行,当选择一行时,它会关闭并通过 ajax 获取记录。

为了阻止用户发送垃圾邮件 ajax 请求,我有一个从指令调用的 debounce 函数。这是通过 keydown 事件触发的。这一切都有效,但不是我需要的方式。我希望在调用 debounce 函数之前调用 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));

在 Controller 中:

$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 上调用的函数,但现在它只是忽略延迟。我不知道如何让它发挥作用。这是我到目前为止所拥有的:

在 Controller 中:

$('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 毫秒。

您应该在 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

关于javascript - 从 keydown 事件监听器中提取去抖函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38025827/

相关文章:

javascript - JS :Select and move a specific div to front

javascript - xPath - 从 anchor 链接中提取 href 的内容

javascript - 带有与 jquery 冲突的段落(下一行)的文本区域

javascript - 如何迭代这个散列?

javascript - Angular JS 范围变量不起作用

javascript - cheerio each() 函数行为异常

javascript - 单击javascript中的下一步按钮后如何显示错误状态?

javascript - Bootstrap 表格和宽度控件

angularjs - AngularJS中具有不同选择值的多个选择框

用于验证输入的 JavaScript 正则表达式是否超过 0 个字符