Eventlistener输入“表单”?

时间:2014-03-01 20:36:49

标签: javascript html css

这是一个我无法处理的常见问题:

在网页上,单击按钮时会显示输入表单。在表单后面我放了一个使页面变暗的背景:

var bgDiv = document.createElement("div");
var formDiv = document.createElement("div");
bgDiv.appendChild(formDiv);
document.body.appendChild(bgDiv);

使用这样的ids和css:

#zreaderwp-bg {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(30, 30, 30, 0.7);
    z-index: 100;
}
#zreader-form {
    margin-top: 100px;
    margin-left: auto;
    margin-right: auto;
    width: 600px;
    height: 600px;
    background: white;
}

我将一个eventlistener附加到bgDiv,希望ESC能隐藏表单:

        bgDiv.addEventListener("keydown", function(ev) {
            ev.stopPropagation();
            console.log("ev.keyCode", ev.keyCode);
            if (27 == ev.keyCode) {
                console.log("was 27");
                bgDiv.style.display = "none";
            }
        });

令我失望的是,这种情况永远不会像我期望的那样发挥作用。原因当然是焦点并不总是在bgDiv中(虽然它在视觉上似乎是这样)。

有没有一种简单的方法来处理这个问题?

更新:我创建了一个小提琴来更好地说明问题,http://jsfiddle.net/lborgman/Musqs/1/。可以看出,移动事件处理程序并不能解决问题。

3 个答案:

答案 0 :(得分:2)

如果您想在全局按下bigDiv时隐藏esc,请将事件监听器添加到document本身(尽管stopPropagation()可能会导致一些问题,所以我已经将其移到if语句中,为了准确性而进行了修改。):

    document.addEventListener("keydown", function(ev) {
        console.log("ev.keyCode", ev.keyCode);
        if (27 == ev.keyCode && bgDiv.style.display !== "none") {
            ev.stopPropagation();
            console.log("was 27");
            bgDiv.style.display = "none";
        }
    });

此外,在if语句中使用三等于===。这里可能不会有太大的变化,但这是一个很好的习惯。有关详细信息,请参阅:== vs ===

提示回答here

答案 1 :(得分:1)

FIDDLE

将其附加到文档而不是在输入内部按下按键时不会阻止事件传播。

你去吧

var docInp = document.getElementById("doc-input");
docInp.focus();
docInp.addEventListener("keydown", function(ev){
    if (27 !== ev.keyCode && bgDiv.style.display !== "none") {
        // we won't stop event propogation if the ESC key was pressed and the bgDiv was visible
        ev.stopPropagation();
    }
    alert("Hi, it's me, docInp? Did u want something?");
});
var bgDiv = document.createElement("div");
bgDiv.setAttribute("id","bg");
var formDiv = document.createElement("div");
formDiv.setAttribute("id","form");
bgDiv.appendChild(formDiv);
formDiv.appendChild(document.createTextNode("Press ESC!"));
document.body.appendChild(bgDiv);


document.addEventListener("keydown", listenToKeys, false);

function listenToKeys(ev) {
    ev.stopPropagation();
    if (27 == ev.keyCode) {
        bgDiv.style.display = "none";
        document.removeEventListener("keydown", listenToKeys, false);
    }
}

答案 2 :(得分:0)

我有点犹豫回答我自己的问题,但由于其他人可能面临同样的问题,所以对我来说看起来最有帮助。昨天与@SomeKittens Ux2666聊天,并且焦点不会留在“bg”里面的问题挣扎,我找到了一个我认为合理的解决方案,请参阅http://jsfiddle.net/lborgman/Musqs/31/

此解决方案使用“focusout”(目前FF不支持,请参阅https://developer.mozilla.org/en-US/docs/Web/Reference/Events/focusout):

        bgDiv.addEventListener("focusout", function(ev){
            // Fix-me: Won't currently work in FF, but it is not
            // really essential and FF will probably support this
            // later.
            ev.stopPropagation();
            var to = ev.relatedTarget;
            var from = ev.target;
            console.log("bg got focusout, to", to, "from", from);
            var inBg = false;
            n = 0;
            while (!inBg && to && n++ < 5) {
                to = to.parentNode;
                inBg = to === bgDiv;
            }
            if (!inBg) {
                console.log("trying to keep focus in bg");
                from.focus();
            }
        });

解决方案的另一半是添加ESC keydown eventlistener的位置。 @SomeKittens和@Lucky Soni的回答已经解决了这个问题,谢谢。 (但是当焦点问题解决后,eventlistener实际上可能会继续“bg”!)