2

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

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

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

谢谢!

4

3 回答 3

2

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

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

如果检测到 keycode,则不要返回 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);
    }
};

Your users can still conveniently make use of spacebars in input textboxes and textareas, and at the same time, pressing the spacebar key while not focused on a text element will no longer result in the page scrolling.

Under the hood, the scroll is still taking place. It's just being reset at a rate fast enough to where the user doesn't notice.

If you increase this value to 100 or 1000, it will give you a better idea of what is going on under the hood. You'll actually see the page scroll and then get set back to the previous scroll position.

This was only tested in Chrome and Firefox 13! So you may have to adjust the setTimeout duration -- currently 0 -- to a different value in browsers like Internet Explorer. Be prepared to gracefully degrade -- by supporting this feature only in modern browsers -- if necessary.

UPDATE:

For reference, below is the method to use to make this compatible in the major browsers. It has been tested in Chrome, Firefox, IE8, IE9, and Safari.

While it does work in IE8/IE9, it isn't very smooth.

// 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;
于 2012-05-19T00:43:58.590 回答
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/

于 2012-05-19T00:25:44.637 回答
1

The answer above with the setTimeout did not work for me at all on Chome with a delay of 0. With a delay bumped above 50ms, it began to work, but that caused a noticeable page jump. I believe that setTimeout was scrolling the page up too early, then Chrome moved it down later.

Below is my solution that is working well. It returns false on the keydown event to prevent the browser from doing a page-down. Then you make sure event you set up on your button etc. to use the keyup event instead.

$(mySelector).keyup(eventHandlerFunction);

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

Note: input fields will not reflect spacebar key events if they or their parent are covered by this onkeydown handler

于 2013-03-19T01:04:23.073 回答