场景:需要绑定 keydown 事件,根据 event.keyCode 来判断是哪个键被按下,做出相应处理;但是不希望用户过于频繁的按键操作,所以用到函数节流,但是 event 对象传递过程中出现一些奇怪的现象,求大佬们解答
以下是部分代码:
// 事件绑定
window.addEventListener('keydown', throttle(keydownHandler, 50, 100, event));
// 函数节流
function throttle(fn, delay, atLeast) {
var timeout = null,
startTime = Date.now(),
args = Array.prototype.slice.call(arguments, 3);
return function () {
var endTime = Date.now();
clearTimeout(timeout);
if(endTime - startTime >= atLeast) {
fn.apply(null, args);
startTime = endTime;
} else {
timeout = setTimeout(function() {
fn.apply(null, args);
}, delay);
}
};
}
// keydown 事件处理程序
function keydownHandler(event) {
var e = event || window.event;
var keyCode = e.keyCode || e.which;
switch (keyCode) {
/*...*/
}
}
然而我在 keydownHandler 中打印 event 得到的结果却是这样的:
事件类型却变成了 load ,求大佬们指点,为什么 event 对象会改变?这里的 event 对象该如何传递呢?
你这个监听函数写得有问题
传给
throttle
函数的event
参数为当前全局的事件对象(可能为undefined
,也可能是其他事件,取决于你调用的环境),所以造成传给keydownHandler
的event
也始终是全局的事件对象。当你触发键盘事件的时候,如果之前传递的全局事件对象为
undefined
,则keydownHandler
内部始终通过window.event
来获取事件对象,而由于setTimeout
的异步效果,当函数被调用的时候,事件对象已经被回收,所以获取keyCode
属性会显示异常。如果之前传递的全局事件对象为确实存在,则在
keydownHandler
内打印event
得到的就是之前传递过来的全局事件对象。编辑: