Когда я щелкаю внутри элемента, который он закрывает, я хочу, чтобы он закрывался, только если они щелкнули за пределами поля.
Как я уже сказал в своем комментарии, если поле содержит другие элементы, то 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;
};
DEMO
Надеюсь, это даст вам некоторое представление. Еще многое можно улучшить, например, теперь менеджер прослушивает каждое событие click
, независимо от того, открыт диалог или нет.