我编写了一些 JavaScript,可以在单击某个元素时打开该元素。但是我无法得到:
var menu = document.getElementById(show);
if (menuOpen && e.target !== menu){...}
这不符合我的要求,因为:
当我一次只想打开一个时,您可以打开多个显示的元素。
当我在元素内部单击时它会关闭,我只希望在他们在框外单击时关闭它。function openBox(button, show){ var menuOpen = false; //to toggle when the button is clicked. // checks the whole document for clicks and then if the element is open it will > // check to see if you have clicked away from it or not. document.addEventListener("click", function(e){ var menu = document.getElementById(show); if (menuOpen && e.target !== menu){ // if elements open and the click event target does not match > menu.style.display = "none"; // we will close it menuOpen = false; } },false); // add an event listner to the button element and then if its clicked stop any > // links an stop bubbling and then change the display style. document.getElementById(button).addEventListener("click", function(e){ var menu = document.getElementById(show); e.preventDefault(); e.stopPropagation(); if (menuOpen){ menu.style.display = "none"; menuOpen = false; } else { menu.style.display = "block"; menuOpen = true; } },false); } openBox("signInButton", "signIn"); openBox("bagButton", "shoppingBag"); openBox("currencyButton", "currencySelect");
http://jsfiddle.net/jamcoupe/9CEGw/
编辑: 在@Felix Kling 发布后,我将代码更改为:
document.addEventListener("click", function(e){
var menu = document.getElementById(show);
if (menuOpen && (e.target.parentNode !== menu) && (e.target !== menu)){
menu.className = "closedBoxes";
pointer = document.getElementById(arrow).className = "arrowE";
menuOpen = false;
}
},false);
这已经解决了第一个问题,但我仍然坚持如何让它在给定时间只打开一个盒子。因此,当用户打开登录框并单击 currencyChanger 时,我希望关闭登录框。
最佳答案
When I click inside the element it closes, I only want it to close if they have clicked outside the box.
正如我在评论中所说,如果框包含其他元素,则 e.target
不是指框本身,而是指框内的元素。
因此,为了测试点击是否在外部,您必须测试 e.target
是框内的元素还是框本身。为此,您必须遍历 DOM 树。
例子:
var target = e.target;
while(target && target !== menu) {
target = target.parentNode;
}
if(!target) {
// click was outside of the box
}
You can open more than one of the showed elements when I only want one open at a time.
如果你想让这三个对话框相互依赖,你必须维护一些共享状态。我建议,您可以使用一个对话框管理器来代替三个对话框,它负责打开和关闭框。
例子:
function DialogManager() {
this.dialogs_ = {};
this.openedDialog_ = null;
this.init_();
}
DialogManager.prototype.init_ = function(e) {
var self = this;
document.addEventListener('click', function(e) {
var id = e.target.id;
if(id && id in self.dialogs_) { // if one of the buttons was clicked.
self.openDialog(id); // the dialog is opened (or closed)
return;
}
if(self.openedDialog_) { // if a dialog is currently open, we have to
var target = e.target; // close it if the click was outside
while(target && target.id !== self.openedDialog_) {
target = target.parentNode;
}
if(!target) {
self.closeDialog(self.openedDialog_);
}
}
}, false);
};
DialogManager.prototype.registerDialog = function(button_id, dialog_id) {
this.dialogs_[button_id] = dialog_id;
};
DialogManager.prototype.openDialog = function(id) {
var open_id = this.openedDialog_;
if(open_id) {
this.closeDialog(open_id);
}
if(id !== open_id) {
var dialog = document.getElementById(this.dialogs_[id]);
dialog.style.display = "block";
this.openedDialog_ = id;
}
};
DialogManager.prototype.closeDialog = function(id) {
var dialog = document.getElementById(this.dialogs_[id]);
dialog.style.display = "none";
this.openedDialog_ = null;
};
我希望这能给你一些想法。还有很多可以改进的地方,例如,现在管理器会监听每个 click
事件,无论对话框是否打开。
关于javascript - 在 JavaScript 中,e.target 没有像我预期的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8777327/