给ul添加click事件监听,当点击子Li时如何获取是点了每几个子元素?

要求原生js方法

我的代码

ULobj.addEventListener('click', 方法名.bind(this, json参数字符串 ));
阅读 4.2k
3 个回答

你打印一下绑定事件的 event 你就知道了,可以从 Event.target 上面获取到对最初分发事件的对象的引用。
但是我找了一圈没有找到元素下标相关的信息,所以如果可以的话,可以直接在 li 元素上面绑定一下自定义的 index 属性,然后去获取:

<ul id="demo">
  <li index="1">one</li>
  <li index="2">two</li>
</ul>
<script>
const el = document.getElementById("demo");
el.addEventListener("click", (event) => {
 console.log(`Clicked li index: ${event.target.attributes.index.value}`);
});
</script>

但是这样我觉得有点怪怪的,去问了一下GPT有什么其他的方式,但是回答更简单粗暴,直接用 querySelectorAll 获取到全部 li 元素之后通过 indexOf 来获取下标信息……


<ul id="demo">
  <li index="1">one</li>
  <li index="2">two</li>
</ul>
<script>
const el = document.getElementById("demo");
el.addEventListener("click", (event) => {
  const clickedLi = event.target;
  const liElements = Array.from(el.querySelectorAll('li'));
  const clickedIndex = liElements.indexOf(clickedLi);
  console.log(`Clicked li index: ${clickedIndex}`);
});
</script>

在绑定事件中,可以通过 event.target 拿到点击的目标元素,再通过 target.parentElement.children 可以拿到目标元素的父元素下所有子元素列表,即可找出当前点击的元素为第几个,示例如下:

<ul id="demo-ul">
  <li>第0项</li>
  <li>第1项</li>
  <li>第2项</li>
</ul>
document.getElementById("demo-ul").addEventListener("click", function (event) {
  const li = event.target;

  const index = Array.from(li.parentElement.children).indexOf(li);

  console.log(`点击了第${index}项`);
});

当然,实际情况中 li 下不一定只是单纯的文字,可能还嵌套了其他元素,那么可以通过 event.target.closest("li") 找到目标元素或其父元素中最近的 li 元素,然后再做判断即可,示例如下:

document.getElementById("demo-ul").addEventListener("click", function (event) {
  const li = event.target.closest("li");

  const index = Array.from(li.parentElement.children).indexOf(li);

  console.log(`点击了第${index}项`);
});

如果 LI 中有多层元素,需要找到最外层的 li,也就是指定 UL 的直接子元素那个 LI。下面的代码是假设 LI 中不会再嵌套 LI 的情况,处理起来会简单一些。

const ulObj = document.getElementById("ulObj");

ulObj.addEventListener(
  "click",
  (e) => {
    const li = findLi(e.target, ulObj);
    if (!li) { return; }
    const idx = [...ulObj.children].indexOf(li);
    console.log(idx);
  }
);

function findLi(target, ul) {
  for (let el = target; !!el; el = el.parentNode) {
    if (el.tagName === "LI") {
      return el;
    }
    if (el === ul) {
      return;
    }
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题