2017-08-31 4 views
0

Ich benutze Firebase DB, um dynamisch einige HTML mit der folgenden Funktion zu generieren.Wie füge ich Ereignis-Listener zur dynamischen Element-ID hinzu?

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

Ich mag mit id="${key}" einen Ereignis-Listener zum ersten td class hinzuzufügen. Ich weiß mit einer normalen id kann ich document.getElementById("xxxx").addEventListener verwenden, aber da dies dynamisch ist und die id ist der Firebase-Schlüssel. Wie füge ich einen Ereignis-Listener mithilfe der Element-ID hinzu?

+1

Sie können eine Klasse hinzufügen, dass dynamische div und dann –

+0

die 'document.getElementById ('$ {key}'). AddEventListener' innen Jobcard Setzen Sie Ereignis-Listener zu dieser Klasse hinzu .. . Roy

+0

@Roy - Das wird nicht funktionieren. Die ständige Änderung von "innerHTML" wird es zerstören. – Quentin

Antwort

1

Erstellen Sie eine Funktion aufrufen, wenn alle data anhängen fertig ist !! Ich testete mit add(), auch für mehr einfach zu handhaben, fügen Sie einen eindeutigen Klassennamen zu td hinzu !!!

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

Danke, es hat funktioniert –

0

Sie können Ereignis Delegation für diesen Einsatz:

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

Ich würde vorschlagen, eine Click-Handler zum #iteminfo Hinzufügen wie sonst würden Sie Stall Ereignis Zuhörer um sich haben, wenn Sie Ihren Tisch reorganisieren.

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

Normalerweise: Genau die gleiche Art und Weise.

Sie haben die ID in einer Variablen. Sie können das Element erhalten. document.getElementById(key).

... aber es gibt ein Problem.

container.innerHTML += jobCard; 

Sie halten den DOM (mit irgendwelchen Elementen Zuhörern daran gebunden) nehmen, um es zu HTML konvertieren (die den Ereignis-Listener über nicht tragen), um es anhängt, dann die HTML-Konvertierung zurück zu DOM (gibt Ihnen einen neuen Satz von Elementen ohne die Ereignis-Listener).


Anstatt die Elemente jedes Mal zu zerstören, sollten Sie sie mit Standard-DOM erstellen. Sie können dann nach dem Erstellen des Elements addEventListener aufrufen.

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

}) 

könnten Sie (entweder mit Ihrem ursprünglichen Ansatz oder in Kombination mit dem oben) delegiert Ereignisse verwenden statt:

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

könnten Sie Ihre Logik ändern, um die td Elemente zu erstellen und fügen Sie die Event-Handler zu ihnen an diesem Punkt. Dies vermeidet das Problem des Löschens des vorhandenen HTML innerhalb der container zusammen mit allen vorhandenen Event-Handlern. Versuchen Sie folgendes:

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

oder das Äquivalent dieser in jQuery wäre:

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

Das ist ein wirklich guter Ansatz –

Verwandte Themen