事件委托和if语句中的元素循环

时间:2019-12-13 10:40:41

标签: javascript for-loop if-statement events event-delegation

我有这个项目,需要在网站导航栏中构建一个通知系统。通过使用Chris at Go make things建议的这种委托事件侦听器方法,可以实现系统的“核心”,您可以在其中侦听DOM元素的单击事件,并一直冒泡到文档。

到目前为止,它一直像一种魅力一样工作,但是我一直停留在这一特定部分中,在该部分中,我需要遍历popup元素中的所有子元素,并将循环的元素包括在if语句中。

我尝试了我可能想到的所有不同循环方法(for,while,forEach等),结果大致相同。使用Array.from将选择器变量(nodeList)手动转换为数组似乎也没有用。这是我的代码的简化版本:

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]部分根本不起作用,单击该变量应包含的任何元素都将运行help_popup_hide函数-不应这样做。该功能仅在其活动状态下在弹出窗口之外单击时才应运行。如果我删除了for循环并手动包含了help_popup_all变量所包含的所有元素,则代码将起作用。

所以我的问题是:如何在if语句中正确包含所有循环的元素?我也欢迎其他解决方案。

-

编辑(12月17日):

以下是Yoshi提供的解决方案,非常适合我的目的。谢谢你耀西!

1 个答案:

答案 0 :(得分:0)

我想您可以简单地使用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>