Я использую 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;
  })
}

Я хочу добавить прослушиватель событий в первый класс td с id="${key}". Я знаю, что с обычным id я могу использовать document.getElementById("xxxx").addEventListener, но так как он динамический, а id является ключом пожарной базы. Как добавить прослушиватель событий, используя идентификатор элемента?

0
e.iluf 31 Авг 2017 в 10:33

5 ответов

Лучший ответ

Создайте функцию для вызова, когда все добавления 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>
1
David Jaw Hpan 31 Авг 2017 в 08:47

Вы можете изменить свою логику, чтобы создать элементы td и добавить к ним обработчик событий. Это позволяет избежать проблемы удаления существующего HTML-кода в container вместе со всеми существующими обработчиками событий. Попробуй это:

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>`);      
});
1
Rory McCrossan 31 Авг 2017 в 07:47

Я бы предложил добавить обработчик щелчков в #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
lumio 31 Авг 2017 в 07:39

Обычно: точно так же.

У вас есть идентификатор в переменной. Вы можете получить элемент. 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
Quentin 31 Авг 2017 в 07:44

Вы можете использовать делегирование событий для этого:

document.addEventListener('click',function(e) {
    if(e.target && e.target.id === "yourID") {
        //do something
    }
});
0
Abbas 31 Авг 2017 в 07:38