[英]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.