2017-08-31 148 views
0

我正在使用firebase DB来动态地使用下面的函数生成一些html。如何将事件侦听器添加到动态元素ID?

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; 
    }) 
} 

我想添加一个事件监听器到第一个TD类与id="${key}"。我知道有一个正常的id我可以使用document.getElementById("xxxx").addEventListener但由于这是动态的,id是火力键。如何使用元素ID添加事件侦听器?

+1

您可以添加一个类,动态格,然后添加事件侦听把'的document.getElementById( '$ {}键')。addEventListener'内jobCard该类 –

+0

.. Roy

+0

@Roy - 那不行。 “innerHTML”的不断变化将会破坏它。 – Quentin

回答

1

创建一个函数,当所有附加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>

+0

谢谢你的工作 –

0

您可以使用事件代表团此:

document.addEventListener('click',function(e) { 
    if(e.target && e.target.id === "yourID") { 
     //do something 
    } 
}); 
1

我建议增加一个单击处理程序到#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>

1

通常情况下:完全相同的方式。

你有一个变量的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); 
    } 
} 
1

你可以改变你的逻辑来创建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>`);  
}); 
+0

这是一个非常好的方法 –

相关问题