事件委托和循环遍历 if 语句中的元素
Event delegation and looping through elements within if-statement
我有这个项目,我需要在站点导航栏中构建一个通知系统。系统的“核心”是通过使用 Chris at Go make things 推荐的委托事件侦听器方法实现的,您可以在其中侦听 DOM 元素的点击事件,它会一直冒泡到文档.
到目前为止,它一直运行得很好,但我一直被困在这个特定的部分,我需要循环遍历弹出元素中的所有子元素,并将循环的元素包含在 if 语句中。
我已经尝试了所有我能想到的不同循环方法(for、while、forEach 等),结果或多或少相同。将选择器变量 (nodeList) 手动转换为带有 Array.from 的数组似乎也无济于事。这是我的代码的简化版本:
const help_target = document.getElementById("help-target"),
help_popup = document.getElementById("help-popup"),
help_popup_all = document.getElementById("help-popup").querySelectorAll('*');
document.addEventListener("click", function(event) {
// Reveal popup element
if(event.target == help_target && !help_target.classList.contains('active')) {
help_popup_reveal();
}
// Hide popup element unless under these conditions
if(event.target != help_target && help_target.classList.contains('active')) {
for (let i = 0; i < help_popup_all.length; i++) {
if(event.target != help_popup || event.target != help_popup_all[i]) {
help_popup_hide();
}
}
}
});
<div id="help">
<p id="help-target">Need help?</p>
<div id="help-popup">
<p><b>Title</b></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
if 语句中的 help_popup_all[i] 部分根本不起作用,单击变量应包含的任何元素 运行s help_popup_hide 函数 -他们不应该这样做。该功能应该 运行 仅当在弹出窗口外单击时处于活动状态。如果我删除 for 循环并手动包含 help_popup_all 变量包含的所有元素,代码就会工作。
所以我的问题是:如何在 if 语句中正确包含所有循环元素?我也愿意接受其他解决方案。
-
编辑(12 月 17 日):
下面 Yoshi 提供的解决方案非常适合我的目的。谢谢耀西!
我想你可以简单地使用 Node.contains()
。含义:根据help_target
是否包含 event.target
.
来决定
const
help_target = document.getElementById('help-target'),
help_popup = document.getElementById('help-popup');
function help_popup_reveal() {
help_popup.style.display = 'block';
help_target.classList.add('active');
}
function help_popup_hide() {
help_popup.style.display = 'none';
help_target.classList.remove('active');
}
document.addEventListener('click', function (evt) {
if (evt.target === help_target && !help_target.classList.contains('active')) {
help_popup_reveal();
return;
}
if (!help_popup.contains(evt.target)) {
help_popup_hide();
}
}, false);
#help, #help-target, #help-popup {
margin: .5rem;
border: 1px solid rgba(0, 0, 0, .2);
background: rgba(0, 0, 0, .2);
}
#help-target.active {
background: green;
}
<div id="help">
<p id="help-target">Need help?</p>
<div id="help-popup" style="display: none">
<p><b>Title</b></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
我有这个项目,我需要在站点导航栏中构建一个通知系统。系统的“核心”是通过使用 Chris at Go make things 推荐的委托事件侦听器方法实现的,您可以在其中侦听 DOM 元素的点击事件,它会一直冒泡到文档.
到目前为止,它一直运行得很好,但我一直被困在这个特定的部分,我需要循环遍历弹出元素中的所有子元素,并将循环的元素包含在 if 语句中。
我已经尝试了所有我能想到的不同循环方法(for、while、forEach 等),结果或多或少相同。将选择器变量 (nodeList) 手动转换为带有 Array.from 的数组似乎也无济于事。这是我的代码的简化版本:
const help_target = document.getElementById("help-target"),
help_popup = document.getElementById("help-popup"),
help_popup_all = document.getElementById("help-popup").querySelectorAll('*');
document.addEventListener("click", function(event) {
// Reveal popup element
if(event.target == help_target && !help_target.classList.contains('active')) {
help_popup_reveal();
}
// Hide popup element unless under these conditions
if(event.target != help_target && help_target.classList.contains('active')) {
for (let i = 0; i < help_popup_all.length; i++) {
if(event.target != help_popup || event.target != help_popup_all[i]) {
help_popup_hide();
}
}
}
});
<div id="help">
<p id="help-target">Need help?</p>
<div id="help-popup">
<p><b>Title</b></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
if 语句中的 help_popup_all[i] 部分根本不起作用,单击变量应包含的任何元素 运行s help_popup_hide 函数 -他们不应该这样做。该功能应该 运行 仅当在弹出窗口外单击时处于活动状态。如果我删除 for 循环并手动包含 help_popup_all 变量包含的所有元素,代码就会工作。
所以我的问题是:如何在 if 语句中正确包含所有循环元素?我也愿意接受其他解决方案。
-
编辑(12 月 17 日):
下面 Yoshi 提供的解决方案非常适合我的目的。谢谢耀西!
我想你可以简单地使用 Node.contains()
。含义:根据help_target
是否包含 event.target
.
const
help_target = document.getElementById('help-target'),
help_popup = document.getElementById('help-popup');
function help_popup_reveal() {
help_popup.style.display = 'block';
help_target.classList.add('active');
}
function help_popup_hide() {
help_popup.style.display = 'none';
help_target.classList.remove('active');
}
document.addEventListener('click', function (evt) {
if (evt.target === help_target && !help_target.classList.contains('active')) {
help_popup_reveal();
return;
}
if (!help_popup.contains(evt.target)) {
help_popup_hide();
}
}, false);
#help, #help-target, #help-popup {
margin: .5rem;
border: 1px solid rgba(0, 0, 0, .2);
background: rgba(0, 0, 0, .2);
}
#help-target.active {
background: green;
}
<div id="help">
<p id="help-target">Need help?</p>
<div id="help-popup" style="display: none">
<p><b>Title</b></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>