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