如何向动态元素Id添加事件侦听器?

时间:2017-08-31 07:33:04

标签: javascript jquery html

我正在使用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添加事件侦听器?

5 个答案:

答案 0 :(得分:1)

我建议在#iteminfo添加一个点击处理程序,否则在重新组织表时会有停顿事件监听器。

&#13;
&#13;
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;
&#13;
&#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
    }
});