Javascript event.target找不到子项。节点列表和HTMLChildren为空

Javascript event.target找不到子项。节点列表和HTMLChildren为空,javascript,html,Javascript,Html,我正试图建立一个菜单与子菜单与香草JavaScript HTML如下所示: <ul id="menu"> <li> <ul> <li>Sub menu item 1</li> <li> <ul> <li>Sub menu of a submenu item 1<

我正试图建立一个菜单与子菜单与香草JavaScript

HTML如下所示:

<ul id="menu">
   <li>
      <ul>
         <li>Sub menu item 1</li>
         <li>
              <ul>
                 <li>Sub menu of a submenu item 1</li>
                 <li>Sub menu of a submenu item 2</li>
            </ul>
         </li>
      </ul>
   </li>
   <li>
      <ul>
         <li>Sub menu item 1</li>
         <li>Sub menu item 2</li>
      </ul>
   </li>
</ul>
为什么event.target.queryselectoral('ul')返回空节点列表

请注意,我将click event(单击事件)置于#菜单而不是#菜单>li上的原因是我不想使用循环在每个li中附加事件处理程序

准确地说,, 单击任何li时,我想检查它是否有子菜单(ul),如果有,我将向单击的“li”添加一个类“open”。 我不在乎li在哪里,我只想知道它是否包含ul


在JQuery中,它应该类似于.find('ul')

我不明白你为什么把事情弄得这么复杂。如果出于任何原因需要,请告知我们

let allLi = document.querySelectorAll("ul:not(#menu) li");
[...allLi].forEach(li => {
 li.addEventListener("click", callThisFunction) 
});

function callThisFunction() {
  console.log(event.target.innerText)
}
编辑: 在下面的评论中解释之后,我做了以下更改:

let allLi = document.querySelectorAll("li");
[...allLi].forEach(li => {
 let method = li.querySelector("ul") ? function1 : function2;
 li.addEventListener("click", method) 
});

function function1() {
  event.stopPropagation();
  console.log(event.target.innerHMTL)
}
function function2() {
  event.stopPropagation();
  console.log(event.target.innerHTML)
}

您的侦听器在顶级菜单上注册,但在处理程序中,您选择忽略ULs上的事件。您仅处理LI上的事件。LI本身没有任何与之关联的UL,并且没有事件侦听器连接到父UL。所以我认为这是正确的


console.log(event.target.parentNode);将为您提供您单击其子项的UL(菜单项)


这是一个需要从头开始解决的棘手问题,尽管我相信这是值得的。这里只是一些开始。你需要解决很多问题,并建立像切换这样的行为

document.addEventListener('DOMContentLoaded',函数(){
var menu=document.getElementById('menu');
menu.addEventListener('click',(e)=>{
e、 预防默认值();
if(e.target.children[0].className=='submenu'){
e、 target.children[0].classList.add('open')
}//在此处添加可选链接
});
});
。子菜单{
显示:无;
}
.打开{
显示:块;
}

  • 选择1
  • 选择2
    • 子菜单项1
    • 子菜单项2
  • 选择3

您是否正在尝试获取子列表的UL?因为单击事件发生在子项
  • 上,而不是在parent.console.log(event.target.parentNode)上;单击#菜单>li时,我想检查它是否有一个ulThen
    if(event.target.matches(“#菜单>li>ul,#菜单>li>ul*”)
    将执行此操作,但您的问题目前没有要求执行此操作。谢谢,不过我需要再次解释。我不想使用forEach或任何类型的循环。这时我在菜单包装器菜单上放置了一个事件。当点击任何LI时,我想检查它是否有子菜单,如果有,那么我将添加一个类“打开”,准确地说,当点击任何LI时,我想检查它是否有子菜单(ul),如果有,那么我将添加一个类“打开”,请查看编辑后的答案。它不包括正确的错误检查,但应该足够好,可以开始使用。我认为有多种方法可以解决这类问题,但这不是一个需要解决的小问题。你可以使用capture vs bubble,或者检查父母、兄弟姐妹和后代,或者像我一样编写CSS类。我认为最简单的选择是在UL和LI上添加类,以指示它们是否有子项。我还没有完全考虑过这一点,但我认为这是最简单的方法。也可以考虑使用现有的解决方案,比如引导手风琴。但从头开始构建它也很有趣D
    let allLi = document.querySelectorAll("li");
    [...allLi].forEach(li => {
     let method = li.querySelector("ul") ? function1 : function2;
     li.addEventListener("click", method) 
    });
    
    function function1() {
      event.stopPropagation();
      console.log(event.target.innerHMTL)
    }
    function function2() {
      event.stopPropagation();
      console.log(event.target.innerHTML)
    }