You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击无序列表子元素时indexOf返回-1,如何获取正确li索引?

问题

尝试从HTML的ul元素中获取其子元素li的索引值,通过[...ul.children]将ul的子元素转换为数组。但点击子元素时,返回的索引值始终为-1而非正确值,是否因为li内部包含div等嵌套元素导致的?

原代码

JavaScript

const ul = document.querySelector('ul');
ul.addEventListener('click', myFunc);

function myFunc(e) {
  const indexToShow = [...ul.children].indexOf(e.target);
  console.log(indexToShow);
  console.log(e.target);
}

HTML

<ul class="calendar-list">
  <li class="list-item">
    <div class="fight-link">
      <span class="date">1 Dec 2022</span>
      <span class="fighters-name">JAY</span>
    </div>
  </li>
  <li class="list-item">
    <div class="fight-link">
      <span class="date">2 Dec 2022</span>
      <span class="fighters-name">Jo</span>
    </div>
  </li>
  <li class="list-item">
    <div class="fight-link">
      <span class="date">3 Dec 2022</span>
      <span class="fighters-name">Bob</span>
    </div>
  </li>
</ul>
解决方案

没错,问题根源就是点击事件的e.target指向的是你实际点击的嵌套元素(比如div、span),而非父级li元素,而ul.children仅包含li元素,所以用嵌套元素在数组中查找,必然返回-1。

以下两种修复方法:

方法一:事件委托+closest()定位父级li

适合li动态增删的场景,通过事件委托在ul上,再找到点击元素对应的li父节点:

const ul = document.querySelector('ul');
ul.addEventListener('click', myFunc);

function myFunc(e) {
  // 向上查找最近的li元素
  const targetLi = e.target.closest('li');
  if (!targetLi) return; // 点击ul空白区域时直接返回,避免报错
  const indexToShow = [...ul.children].indexOf(targetLi);
  console.log(indexToShow);
  console.log(targetLi);
}

closest('li')会从当前点击的元素开始向上遍历DOM树,返回第一个匹配的li元素,完美解决嵌套元素的问题。

方法二:直接给li绑定点击事件

适合静态列表(li不会动态变化),遍历li时直接拿到索引:

const lis = document.querySelectorAll('li');
lis.forEach((li, index) => {
  li.addEventListener('click', () => {
    console.log(index);
    console.log(li);
  });
});

这种方式无需额外查找,直接在遍历过程中获取索引,逻辑更简洁。

内容的提问来源于stack exchange,提问作者Pro Girl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:12:10