我正在使用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添加事件侦听器?
答案 0 :(得分: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 );
&#13;
<div id="iteminfo"></div>
&#13;
答案 1 :(得分: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);
}
}
答案 2 :(得分: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>`);
});
答案 3 :(得分: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>
答案 4 :(得分:0)
您可以使用事件委派:
document.addEventListener('click',function(e) {
if(e.target && e.target.id === "yourID") {
//do something
}
});