簡體   English   中英

如何在具有交互式內容的動態創建的 div 上添加事件偵聽器

[英]How to add event listener on dynamically created div with interactive content

在搜索如何將事件偵聽器附加到動態加載的 div時,接受的答案似乎是事件委托。 當 HTML 與insertAdjacentHTML添加時,我沒有找到另一種建議的方式。

我正在向 DOM 添加 div,如下所示:

 document.getElementById('container').insertAdjacentHTML( 'beforeend', `<div class="card"> <div class="card-header">Card header content</div> <div class="card-body"> <h2>Card body</h2> <select> <option value="value1">Value 1</option> </select><br> Some more text </div> </div>` ); // Event delegation document.addEventListener('click', function (e) { console.log(e.target.className); });
 .card{ background: rosybrown; text-align: center; width: 50%; } h2{ margin-top: 0; }
 <div id="container"> </div>

我希望您在單擊卡上的任何位置時都能看到控制台 output。

事件委托我如何知道它的工作原理是通過將單擊事件附加到像document這樣的“大”父元素上,然后比較被單擊元素的類名等屬性,並在它與預期的className名稱匹配時進行一些操作。

問題是這個event.target以卡片內精確點擊的元素為目標,但我不能對這些信息做太多,可以嗎? 我需要整個卡片(這些元素的父級)才能為用戶做出正確的操作(在這種情況下,重定向到卡片預覽的更詳細視圖)。

我認為,一個骯臟的可能解決方案是用<a> -tag 包裝 div,但隨后select和卡的其他按鈕/交互元素將不起作用,用戶只會被引導到鏈接。

您可以使用Element.closest來檢索您需要的元素。

 document.getElementById('container').insertAdjacentHTML( 'beforeend', `<div class="card"> <div class="card-header">Card header content</div> <div class="card-body"> <h2>Card body</h2> <select> <option value="value1">Value 1</option> </select><br> Some more text </div> </div>` ); // Event delegation document.addEventListener('click', function (e) { console.clear(); console.log(e.target.closest(`.card`)); });
 .card{ background: rosybrown; text-align: center; width: 50%; } h2{ margin-top: 0; }
 <div id="container"> </div>

您可以嘗試以這種方式創建卡片並為它們分配偵聽器,然后使用this而不是e.target

 const cardElement = document.createElement('div') cardElement.classList.add('card') cardElement.insertAdjacentHTML( 'beforeend', ` <div class="card-header">Card header content</div> <div class="card-body"> <h2>Card body</h2> <select> <option value="value1">Value 1</option> </select><br> Some more text </div>`) document.getElementById('container').appendChild(cardElement); // Event delegation cardElement.addEventListener('click', function (e) { console.clear() console.log(this); });
 .card{ background: rosybrown; text-align: center; width: 50%; } h2{ margin-top: 0; }
 <div id="container"> </div>

我只是對@KooiInc 的回答進行了一些擴展,所有的贊譽和支持都應該 go 到 KooiInc ...... .closest()是一個很好的事件委托工具。

我認為通過放入第二張卡片可以更清楚地展示這個概念。 我添加了一個cardId ,因此可以在控制台 output 中清楚地看到找到了哪張卡。

我還將委托從document移到了#container如果將委托偵聽器下推到包含您感興趣的對象的最近元素,您可以處理更少的點擊事件。

 const container = document.getElementById('container'); let cardId = 1; // Add the 1st card container.insertAdjacentHTML( 'beforeend', `<div class="card" id="${cardId}"> <div class="card-header">Card header content</div> <div class="card-body"> <h2>Card ${cardId} Body</h2> <select> <option value="value${cardId}">Value ${cardId}</option> </select><br> Some more text </div> </div>` ); // Add a 2nd card ++cardId; container.insertAdjacentHTML( 'beforeend', `<div class="card" id="${cardId}"> <div class="card-header">Card header content</div> <div class="card-body"> <h2>Card ${cardId} Body</h2> <select> <option value="value${cardId}">Value ${cardId}</option> </select><br> Some more text </div> </div>` ); // Event delegation container.addEventListener('click', function (e) { console.clear(); console.log(e.target.closest(`.card`)); });
 .card{ background: rosybrown; text-align: center; width: 50%; }.card +.card { margin-top: 1rem; } h2{ margin-top: 0; }
 <div id="container"> </div>

在現實生活中,我可能會將大部分內容放在addCard() function 中。

暫無
暫無

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

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