仅在显示元素时才阻止使用键盘滚动网页

问题描述 投票:0回答:1

在网页上,某些键盘按键会控制网页的滚动,例如空格键、向上箭头、向下箭头。

我打算在显示覆盖元素时阻止用户使用这些键滚动。该覆盖元素的默认值为

display: none;

我理解“不要改变浏览器的行为”的情绪,但滚轮和/或触摸板(当然还有滚动条)仍然允许滚动。
当叠加显示时,这些按键仅用于控制叠加内容,而不是页面滚动。
相应地,当不显示覆盖层时,按键应恢复滚动页面的默认行为。

因此,我正在考虑使用 EventListener,并且我找到了一个 here:

window.addEventListener("keydown", function(e) {
    if([" ","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
        e.preventDefault();
    }
}, false);

示例代码片段:

function launchOverlay() {
    overlay.style.display = "flex";

    window.addEventListener("keydown", function(e) {
        if([" ","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
            e.preventDefault();
        }
    }, false);
}

function closeOverlay() {
    overlay.style.display = "none";

    window.removeEventListener("keydown", function(e) {
        if([" ","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
            e.preventDefault();
        }
    }, false);
}

document.addEventListener('keydown', function(event) {
    if (overlay.style.display == "flex") {
        if (event.code === "Space") {
            space();
        } else if (event.code === "ArrowUp") {
            aUp();
        } else if (event.code === "ArrowDown") {
            aDown();
        } else if (event.code === "ArrowLeft") {
            aLeft();
        } else if (event.code === "ArrowRight") {
            aRight();
        } else if (event.code === "Escape") {
            closeOverlay();
        }
    }
});

我想知道如何仅在显示覆盖元素时分配 EventListener。目前,我的箭头键仍处于“劫持”状态,在覆盖层关闭后将无法运行。如果我再次打开叠加层,它会按照我指定的方式运行。

javascript scroll keyboard overlay arrow-keys
1个回答
0
投票

您的问题是您实际上并没有删除用于防止滚动的 EventListener。

为此,您可以这样做:

function launchOverlay() {
    overlay.style.display = "flex";
    window.addEventListener("keydown", scroll);
}

function closeOverlay() {
    overlay.style.display = "none";
    window.removeEventListener("keydown", scroll);
}

function scroll(e) {
    if([" ","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
        e.preventDefault();
    }
}

但是由于您在防止滚动的同时重新分配这些箭头键,因此您应该在一个函数中包含此代码块,以便您可以将其作为事件监听器添加/删除。

当您打开叠加层时,请包含事件监听器以防止通过

addEventListener
滚动。
同样,当您关闭叠加层时,请删除 EventListener,
removeEventListener


在这段代码中,我选择了 switch 而不是 if-else。
我还使用

key
而不是
code
,因为
e.code
不考虑用户的键盘布局,并且可能返回意外值。 了解更多

function launchOverlay() {
    overlay.style.display = "flex";
    window.addEventListener("keydown", keyboardNav);
}

function closeOverlay() {
    overlay.style.display = "none";
    window.removeEventListener("keydown", keyboardNav);
}


// Define EventListener toggle
function keyboardNav(e) {
    // Prevent scrolling
    if ([" ", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].indexOf(e.key) > -1) {
        e.preventDefault();
    }

    // When overlay is on, what do the keys do?
    if (overlay.style.display == "flex") {
        switch (e.key) {
            case " ":
                space();
                break;
            case "ArrowUp":
                aUp();
                break;
            case "ArrowDown":
                aDown();
                break;
            case "ArrowLeft":
                aLeft();
                break;
            case "ArrowRight":
                aRight();
                break;
            case "Escape":
                closeOverlay();
                break;
            default:
                break;
        }
    }
}

这样,

keyboardNav()
中的所有内容都只会在运行
launchOverlay()
后使用,并在
closeOverlay()
之后被“忽略”。

© www.soinside.com 2019 - 2024. All rights reserved.