我有一个表,可以使用向上/向下箭头选择行,当选择一行时,它会关闭并通过 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/