我写了一些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);
这解决了第一个问题,但我仍然坚持如何制作它,以便只有一个盒子在一个给定时间打开。因此,当用户打开signIn框并点击currencyChanger时,我希望signIn框关闭。
答案 0 :(得分:1)
当我在它关闭的元素内部点击时,我只希望它在盒子外面点击时关闭。
正如我在评论中已经说过的那样,如果框中包含其他元素,则e.target
不会引用框本身,而是引用框内的元素。
因此,为了测试点击是否在外,您必须测试e.target
是否是框内的元素或框本身。为此,您必须遍历DOM树。
示例:
var target = e.target;
while(target && target !== menu) {
target = target.parentNode;
}
if(!target) {
// click was outside of the box
}
当我只希望一次打开时,您可以打开多个显示的元素。
如果要使三个对话框相互依赖,则必须保持一些共享状态。我建议,您可以使用一个对话管理器来处理打开和关闭框,而不是有三个对话框。
示例:
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
事件,无论对话是否打开。