簡體   English   中英

如何為動態子項分配單擊事件偵聽器?

[英]How to assign dynamic children a click event listener?

我有一個包含許多元素的父容器,它不是一個明確定義的元素數量,它是在用戶開始在輸入字段中輸入內容時使用 API 生成的。 這些元素也是其他元素的父元素。 (下面我舉個例子)

這個想法是,一旦用戶單擊該元素,我想顯示一個覆蓋層,其中包含有關該特定元素的更多信息。 聽起來不錯,但我嘗試過的東西到目前為止還沒有奏效。

我試圖在容器上添加一個事件監聽器。 考慮這個基本的 HTML 模板。

<ul>
  <li><span>Item 1</span><span>X</span></li>
  <li><span>Item 2</span><span>X</span></li>
  <li><span>Item 3</span><span>X</span></li>
  <li><span>Item 4</span><span>X</span></li>
</ul>

<form>
  <input type="text" id="test">
</form>

所以這里我們有一個 UL,它是父元素,LI 是它的子元素。 但是,LI 也是 span 標簽的父級,這些標簽應該顯示一些重要信息,因此我無法刪除這些標簽。 輸入字段在這里只是為了動態添加一些東西,模仿我的 API 的工作方式。

所以就像我說的,我試圖在 UL 父級上添加一個事件監聽器 >>

  const items = ul.querySelectorAll('li');
  items.forEach(item => item.addEventListener('click', function(e) {
  console.log(this);
  }));
});
});

然后我嘗試為每個項目添加一個事件偵聽器,但不是在單擊它們時一次記錄一個項目,而是記錄一個、兩個、三個等等。 我覺得我在這里遺漏了一些東西,我不知道它是什么。 你們能幫幫我嗎?

稍后編輯:我找到了這個解決方案,但它對我來說似乎不是很優雅,如果我稍后更改內容(如添加更多孩子等),它很容易出現錯誤。

ul.addEventListener('click', e => {
  const items = ul.querySelectorAll('li');
  if(e.target.tagName === 'LI' || e.target.parentElement.tagName === 'LI') {
    if(e.target.tagName === 'LI') {
      e.target.remove();
    } else if(e.target.parentElement.tagName === 'LI') {
      e.target.parentElement.remove();
    }
  }
});

您可以使用 function Element.closest()來查找父元素。

 const ul = document.querySelector('ul'); ul.addEventListener('click', e => { let li = e.target.closest('LI'); li.remove(); }); document.forms.newitem.addEventListener('submit', e => { e.preventDefault(); let newitem = document.createElement('LI'); newitem.innerText = e.target.test.value; ul.appendChild(newitem); });
 <ul> <li><span>Item 1</span><span>X</span></li> <li><span>Item 2</span><span>X</span></li> <li><span>Item 3</span><span><em>X</em></span></li> <li>Item 4 X</li> </ul> <form name="newitem"> <input type="text" name="test"> </form>

每次單擊一行時都會收到所有行事件的原因是您在ul元素中添加了一個事件單擊,而您只需要在li元素中使用它

您想要的一種非常相似的方式:

 let ul = document.querySelector("ul"); const items = ul.querySelectorAll("li"); items.forEach((item) => item.addEventListener("click", function (e) { let getTargetRow = e.target.parentElement; if (getTargetRow.nodeName === "LI"){ console.log("the line removed:",getTargetRow.textContent); getTargetRow.remove(); } }) );
 <ul> <li><span>Item 1</span><span>X</span></li> <li><span>Item 2</span><span>X</span></li> <li><span>Item 3</span><span>X</span></li> <li><span>Item 4</span><span>X</span></li> </ul> <form> <input type="text" id="test" /> </form>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM