Я использую 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
является ключом пожарной базы. Как добавить прослушиватель событий, используя идентификатор элемента?
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>
Вы можете изменить свою логику, чтобы создать элементы 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>`);
});
Я бы предложил добавить обработчик щелчков в #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>
Обычно: точно так же.
У вас есть идентификатор в переменной. Вы можете получить элемент. 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);
}
}
Вы можете использовать делегирование событий для этого:
document.addEventListener('click',function(e) {
if(e.target && e.target.id === "yourID") {
//do something
}
});
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.