【问题标题】:Clicking outside of element with JavaScript e.target not working使用 JavaScript e.target 在元素外部单击不起作用
【发布时间】:2021-12-21 12:26:52
【问题描述】:

我正在构建一个超级菜单,每个菜单上都有一个关闭按钮,效果很好。但是我需要编写一些 JavaScript 来说明,“如果您在打开的大型菜单之外单击,请关闭它”。

我在下面写了一个脚本。它确实会检测用户何时在超级菜单内部单击,但当他们在其外部单击时不会检测到。在这种情况下,删除使元素具有display: block;display-on 类。

const dropDownMenu = document.getElementsByClassName("drop-down");

for (let i = 0; i < dropDownMenu.length; i++) {
  dropDownMenu[i].addEventListener("click", (e) => {
    // If clicking in any area that has drop-down class, do nothing.
    if (dropDownMenu[i].contains(e.target)) {
      console.log("clicked in mega menu area");
      // If clicking in any area outside drop-down class, remove display-on class which closes the menu.
    } else {
      console.log("clicked outside mega menu area");
      document.querySelector(".display-on").classList.remove("display-on");
    }
  });
}

如果需要可以查看工作演示here

谢谢。

【问题讨论】:

  • 当然,OP 需要在任何 drop-down 分类元素之外注册对 “out of drop-down” 事件的处理。 document.body 可能是适合聆听的元素。

标签: javascript dom event-handling dom-events event-delegation


【解决方案1】:

从上面的评论...

“因为 OP 需要在任何 drop-down 分类元素之外注册对 “out of drop-down” 事件的处理。document.body 可能是正确的元素听。”

...类似这样的...

function handleDropDownMenuBehavior(evt) {
  if (evt.target.closest('.drop-down') === null) {

    document.querySelector(".display-on").classList.remove("display-on");

    console.log("clicked outside mega menu area");
  } else {
    console.log("clicked in or at mega menu area");
  }
}
document.body.addEventListener('click', handleDropDownMenuBehavior);

【讨论】:

  • 试过了,当我单击任何下拉父链接以显示菜单时,单击它会自动删除大型菜单本身的显示类。因此,巨型菜单不显示,因为 display-on 类被剥离,使菜单根本不显示。有没有办法只在超级菜单打开并且用户点击离开超级菜单之后才编写上面的代码?
  • @infused ...当然,如果您提供最必要的 html 和 css。对于我上面的示例,我从原始帖子的示例代码中得到的只是drop-down 类名。您还需要提供实际触发菜单显示的代码。
  • @infused ... 还在我们身边吗?
【解决方案2】:

您可以在文档中添加一个全局事件侦听器,以检查单击的内容是否不是超级菜单。如果您需要任何额外的帮助,请告诉我:)

document.onclick = (e) => {
    if (e.target.contains(document.getElementsByClassName("drop-down")[0])) {
        console.log('close mega menu');
        document.getElementsByClassName("drop-down")[0].classList.remove("display-on");
    }
}

【讨论】:

  • 这确实有效,但仅适用于第一个下拉项目(在本例中为“租赁设备”菜单)。但不是任何其他大型菜单。我们怎样才能使这项工作不仅影响第一个项目 [0],而且影响所有大型菜单?
  • 想通了!添加了一个 for 循环,因为我必须遍历所有这些循环,然后在出现 display-on 元素时删除 display-on 类:document.onclick = (e) =&gt; { for (let i = 0; i &lt; dropDownMenu.length; i++) { if (e.target.contains(dropDownMenu[i])) { document.querySelector(".display-on").classList.remove("display-on"); } } };
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2017-09-09
  • 2018-09-20
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
相关资源
最近更新 更多