我正在使用画布和 javascript 制作游戏。
当页面长于屏幕(评论等)时,按向下箭头可将页面向下滚动,并使游戏无法进行。
当玩家只想向下移动时,我该怎么做才能防止窗口滚动?
我想对于 Java 游戏等,这不是问题,只要用户点击游戏即可。
我尝试了以下解决方案:How to disable page scrolling in FF with arrow keys,但我无法让它工作。
我正在使用画布和 javascript 制作游戏。
当页面长于屏幕(评论等)时,按向下箭头可将页面向下滚动,并使游戏无法进行。
当玩家只想向下移动时,我该怎么做才能防止窗口滚动?
我想对于 Java 游戏等,这不是问题,只要用户点击游戏即可。
我尝试了以下解决方案:How to disable page scrolling in FF with arrow keys,但我无法让它工作。
只需阻止默认浏览器操作:
window.addEventListener("keydown", function(e) {
if(["Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
e.preventDefault();
}
}, false);
如果您需要支持 Internet Explorer 或其他较旧的浏览器,请使用e.keyCode
代替e.code
,但请记住,keyCode
它已被弃用,您需要使用实际代码而不是字符串:
// Deprecated code!
window.addEventListener("keydown", function(e) {
// space and arrow keys
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
}, false);
我在自己的游戏中使用了以下功能:
var keys = {};
window.addEventListener("keydown",
function(e){
keys[e.code] = true;
switch(e.code){
case "ArrowUp": case "ArrowDown": case "ArrowLeft": case "ArrowRight":
case "Space": e.preventDefault(); break;
default: break; // do not block other keys
}
},
false);
window.addEventListener('keyup',
function(e){
keys[e.code] = false;
},
false);
魔法发生在e.preventDefault();
. 这将阻止事件的默认操作,在这种情况下移动浏览器的视点。
如果您不需要当前按钮状态,您可以简单地删除keys
并丢弃箭头键上的默认操作:
var arrow_keys_handler = function(e) {
switch(e.code){
case "ArrowUp": case "ArrowDown": case "ArrowLeft": case "ArrowRight":
case "Space": e.preventDefault(); break;
default: break; // do not block other keys
}
};
window.addEventListener("keydown", arrow_keys_handler, false);
请注意,如果您需要重新启用箭头键滚动,此方法还允许您稍后删除事件处理程序:
window.removeEventListener("keydown", arrow_keys_handler, false);
window.addEventListener
window.removeEventListener
KeyboardEvent.code
接口为了可维护性,我会在元素本身(在您的情况下,画布)上附加“阻塞”处理程序。
theCanvas.onkeydown = function (e) {
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
e.view.event.preventDefault();
}
}
为什么不干脆做window.event.preventDefault()
?MDN声明:
window.event
是专有的 Microsoft Internet Explorer 属性,仅在调用 DOM 事件处理程序时可用。它的值是当前正在处理的 Event 对象。
进一步阅读:
我尝试了不同的方法来阻止按下箭头键时的滚动,包括 jQuery 和本机 Javascript - 它们在 Firefox 中都可以正常工作,但在最新版本的 Chrome 中不起作用。
即使是显式{passive: false}
属性 for window.addEventListener
,它被推荐为唯一的工作解决方案,例如这里。
最后,经过多次尝试,我找到了一种在 Firefox 和 Chrome 中都适用的方法:
window.addEventListener('keydown', (e) => {
if (e.target.localName != 'input') { // if you need to filter <input> elements
switch (e.keyCode) {
case 37: // left
case 39: // right
e.preventDefault();
break;
case 38: // up
case 40: // down
e.preventDefault();
break;
default:
break;
}
}
}, {
capture: true, // this disables arrow key scrolling in modern Chrome
passive: false // this is optional, my code works without it
});
EventTarget.addEventListener()
来自MDN 的报价
选项可选
选项对象指定有关事件侦听器的特征。可用的选项是:capture
ABoolean
指示这种类型的事件将被分派给注册的,listener
然后再分派到EventTarget
DOM 树中它下面的任何一个。
一次
...
被动
ABoolean
,如果为真,则表示由 指定的函数listener
将永远不会调用preventDefault()
。如果被动侦听器确实调用了preventDefault()
,则用户代理除了生成控制台警告之外什么也不做。...
这是为 React 重写的公认答案。
import { useEffect } from "react";
const usePreventKeyboardScrolling = () => {
const onKeyDown = (e) => {
if (
["Space", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].indexOf(
e.code
) > -1
) {
e.preventDefault();
}
};
useEffect(() => {
window.addEventListener("keydown", onKeyDown, false);
return () => window.removeEventListener("keydown", onKeyDown);
});
};
export { usePreventKeyboardScrolling };