这个JavaScript代码是否会通过禁用一个键来影响其他按键事件?

时间:2012-05-19 00:20:27

标签: javascript jquery keypress dom-events

我正在使用它来禁用空格键在浏览器中的“滚动”效果。这会影响其他按键事件吗?

window.onkeydown = function(e) {
    return !(e.keyCode == 32);
};

有人可以解释一下这是做什么的吗?我不确定这段代码是不是很糟糕,但似乎在我的页面中禁用了其他与按键相关的代码,我想确保这不是原因。

谢谢!

3 个答案:

答案 0 :(得分:2)

ASCII码32是表示空格键的ASCII值,您的代码实际上是告诉浏览器在检测到键码时返回false。由于返回false,因此您所说的滚动条效果实际上已成功禁用。

然而,这种方便的空格键滚动禁用功能的不幸副作用是它禁用页面上任何位置的空格键按键。

如果检测到键码,则不是返回false,而是将当前的scrollTop值传递给闭包,该闭包将函数返回给setTimeout事件。触发setTimeout时,scrollTop位置将重置为首次注册setTimeout事件时的值。

window.onkeydown = function(e) {
    if(event.keyCode == 32) { // alert($(document).scrollTop() );
        setTimeout(                 
            (function(scrollval) { 
                return function() { 
                    $(document).scrollTop(scrollval);
                };
            })( $(document).scrollTop() ), 0);
    }
};

您的用户仍然可以方便地在输入文本框和文本区中使用空格键,同时按空格键而不关注文本元素将不再导致页面滚动。

在引擎盖下,卷轴仍在进行中。它只是以足够快的速度重置到用户不注意的地方。

如果将此值增加到100或1000,它将使您更好地了解幕后发生的情况。您实际上会看到页面滚动,然后回到上一个滚动位置。

这只在Chrome和Firefox 13中测试过!因此,您可能需要在Internet Explorer等浏览器中将setTimeout持续时间(当前为0)调整为不同的值。准备优雅降级 - 只在现代浏览器中支持此功能 - 如有必要。

<强>更新

供参考,以下是在主要浏览器中使其兼容的方法。它已在Chrome,Firefox,IE8,IE9和Safari中进行过测试。

虽然它在IE8 / IE9中可行,但它不是很流畅。

// put the eventhandler in a named function so it can be easily assigned
   // to other events.
function noScrollEvent(e) {
    e = e || window.event;
    if(e.keyCode == 32) {  
        setTimeout(                 
            (function(scrollval) { 
                return function() { 
                    $(document).scrollTop(scrollval);
                };
            })( $(document).scrollTop() ), 0);
    }
}


// Chrome and Firefox must use onkeydown
window.onkeydown = noScrollEvent;

// Internet Explorer 8 and 9 and Safari must use onkeypress
window.document.onkeypress = noScrollEvent;

答案 1 :(得分:1)

如果另一个元素绑定到keydown事件,它将不受此代码

的影响

看到我的小提琴并尝试添加并删除听取keydown事件的textarea

window.onkeydown = function(e) {
    return !(e.keyCode == 32);
};

document.getElementsByTagName("textarea")[0].onkeydown = function(e) {
    alert("hi");
}

http://jsfiddle.net/HnD4Y/

答案 2 :(得分:1)

上面使用setTimeout的答案对于我来说根本不适用于延迟为0的Chome。延迟超过50ms后,它开始工作,但这导致了明显的页面跳转。我相信setTimeout过早地滚动页面,然后Chrome将其向下移动。

以下是我的解决方案,运作良好。它在keydown事件上返回false以防止浏览器执行向下翻页。然后,确保在按钮等上设置的事件代替使用keyup事件。

$(mySelector).keyup(eventHandlerFunction);

[dom element].onkeydown = function(event) {
  if (event.keyCode == 32) {return false;}
};

注意:输入字段不会反映空格键事件,如果它们或它们的父项被此onkeydown处理程序覆盖