这是一个我无法处理的常见问题:
在网页上,单击按钮时会显示输入表单。在表单后面我放了一个使页面变暗的背景:
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/。可以看出,移动事件处理程序并不能解决问题。
答案 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)
将其附加到文档而不是在输入内部按下按键时不会阻止事件传播。
你去吧
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”!)