[英]How do I add event listener to dynamic element Id?
我正在使用Firebase DB使用以下功能动态生成一些html。
function Inventorytable(data) {
var container = document.getElementById('iteminfo');
container.innerHTML = '';
data.forEach(function(InventSnap) { // loop over all jobs
var key = InventSnap.key;
var Items = InventSnap.val();
var jobCard = `
<td class="text-left" id="${key}"><a href>${key}</a href></td>
<td class="text-left" >${Items.PartNumber}</td>
`;
container.innerHTML += jobCard;
})
}
我想使用id="${key}"
将事件侦听器添加到第一个td类。 我知道使用常规id
可以使用document.getElementById("xxxx").addEventListener
但是由于这是动态的,因此id
是Firebase密钥。 如何使用元素ID添加事件监听器?
我建议将点击处理程序添加到#iteminfo
,否则您在重新组织表格时会遇到停顿事件监听器。
var container = document.getElementById('iteminfo'); container.addEventListener( 'click', ( e ) => { const id = e.target.id; console.log( id ); } ); var data = [ { key: 1 }, { key: 2 }, { key: 3 }, { key: 'some-other-key' }, ] function Inventorytable(data) { container.innerHTML = ''; data.forEach(function(InventSnap) { // loop over all jobs var key = InventSnap.key; var jobCard = `<button id="${key}">${ key }</button>`; container.innerHTML += jobCard; }) } Inventorytable( data );
<div id="iteminfo"></div>
通常:完全相同。
您在变量中具有ID。 您可以获取元素。 document.getElementById(key)
。
……但是有一个问题。
container.innerHTML += jobCard;
您继续获取DOM(绑定了任何元素侦听器),将其转换为HTML(不携带事件侦听器),附加到该内容,然后将HTML转换回DOM(为您提供了一组新的元素)没有事件监听器)。
与其每次都破坏元素,不如使用标准DOM创建它们。 然后,您可以在创建元素后调用addEventListener
。
data.forEach(function(InventSnap) { // loop over all jobs
var key = InventSnap.key;
var Items = InventSnap.val();
var td = document.createElement("td");
td.setAttribute("class", "text-left");
td.setAttribute("id", key);
td.addEventListener("click", your_event_listener_function);
var a = document.createElement("a");
a.setAttribute("href", "");
a.appendChild(document.createTextNode(key));
td.appendChild(a);
container.appendChild(td);
td = document.createElement("td");
td.setAttribute("class", "text-left");
td.appendChild(document.createTextNode(Items.PartNumber));
container.appendChild(td);
})
您可以(使用原始方法或与上述方法组合使用)委托事件来代替:
container.addEventListener("click", delegated_event_listener);
function delegated_event_listener(event) {
if (test_what_element_was_clicked_on(this)) {
do_something_with(this.id);
}
}
您可以更改逻辑以创建td
元素,然后在该点添加事件处理程序。 这样可以避免删除container
现有的HTML以及所有现有的事件处理程序的问题。 尝试这个:
data.forEach(function(InventSnap) { // loop over all jobs
var key = InventSnap.key;
var Items = InventSnap.val();
var td0 = document.createElement('td');
td0.id = key;
td0.classList.add('text-left');
container.appendChild(td0);
td0.addEventListener('click', function() {
console.log('clicked!');
});
var a = document.createElement('a');
a.href = '#';
a.innerText = key;
td0.appendChild(a);
var td1 = document.createElement('td');
td1.innerText = Items.PartNumber;
td1.classList.add('text-left');
container.appendChild(td1);
});
或等效于jQuery的是:
data.forEach(function(inventSnap) {
var key = inventSnap.key;
var items = inventSnap.val();
var $td = $(`<td class="text-left" id="${key}"><a href="#">${key}</a></td>`).on('click', function() {
console.log('clicked!');
}).appendTo(container);
container.append(`<td class="text-left">${items.PartNumber}</td>`);
});
创建一个函数,当所有附加data
完成时调用! 我用add()
进行了测试,也为了更易于处理,在td
添加了一个不同的类名!
var data = [ {key:0,val:"Zero"}, {key:1,val:"One"} ] Inventorytable(data); function Inventorytable(data) { var container = document.getElementById('iteminfo'); container.innerHTML = ''; data.forEach(function(InventSnap) { // loop over all jobs var key = InventSnap.key; var Items = InventSnap.val; var jobCard = ` <td class="text-left first" id="${key}"><a href="#!">${key}</a href></td> <td class="text-left" >${Items}</td> `; container.innerHTML += jobCard; }); add(); } function add() { var container = document.querySelectorAll(".first"); [].map.call(container, function(elem) { elem.addEventListener("click",function(){ console.log(this.id); }, false); }); }
<table> <tr id="iteminfo"></tr> </table>
您可以为此使用事件委托:
document.addEventListener('click',function(e) {
if(e.target && e.target.id === "yourID") {
//do something
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.