2015-06-21 7 views
5

ich eine Menge von DOM-Elementen zu schaffen (jeweils die gleiche HTML-Struktur) mit dem <template> tag:Hinzufügen von Ereignis-Listener auf Elemente aus der Vorlage Tag kloniert

<template id="weapon-template"> 
    <div class="button"> 
     <div class="button-price" data-price ></div> 
     <img class="button-image" data-image > 
     <div class="button-name" data-name ></div> 
     <div class="button-damage" data-damage></div> 
     <div class="button-amount" data-amount></div> 
    </div> 
</template> 

... und ein paar Zeilen JavaScript :

var clone; 
var template = document.getElementById("weapon-template"); 

template.content.querySelector("[data-image]" ).src = data.prev; 
template.content.querySelector("[data-price]" ).innerHTML = data.cost + "$"; 
template.content.querySelector("[data-name]" ).innerHTML = data.name; 
template.content.querySelector("[data-damage]").innerHTML = data.damage; 
template.content.querySelector("[data-amount]").innerHTML = 0; 

clone = document.importNode(template.content, true) 
this.container.appendChild(clone); 

ich würde gerne einige Event-Listener auf den geklonten Elemente hinzuzufügen. Ich konnte nichts aus dem Internet finden und müde ein paar Dinge mein Selbst, wie:

template.content.querySelector("[data-price]").addEventListener("click", action, false); 
clone.querySelector("[data-price]").addEventListener("click", action, false); 

... keiner von diesen funktioniert. Ich könnte einfach so etwas wie:

var child = this.container.childNodes[ 0 ]; 
var target = child.querySelector("[data-price]"); 

target.addEventListener("click", action, false); 

... aber ich frage mich, ob es eine andere, einfachere Art und Weise ähnlich denen, die nicht für mich gearbeitet hat.

+0

Warum wählen Sie nach 'data- *' Attributen? –

+0

@Jamen Einfach weil ich keine ID-Duplikate haben will. – guest459473

+0

@Jamen Klassennamen können sich jederzeit ändern, zum Beispiel wenn ich neue Buttons entwerfe und mit einer anderen HTML-Struktur, etc. In diesem Fall sind 'data- * 'Attribute genau wie ID's, also kann ich JS trennen Funktionalität aus dem CSS-Design. – guest459473

Antwort

4

Bis Sie eine Vorlage mit document.importNode "aktivieren", sind deren Inhalt inerte Knoten, die nicht Teil von DOM sind.

Wie pro addEventListener docs:

Das Ereignisziel kann ein Element in einem Dokument sein, das Dokument selbst, ein Fenster oder jedes anderes Objekt, das Ereignis (wie XMLHttpRequest) unterstützt.

Deshalb Hinzufügen Ereignis-Listener in Ihrem Beispiel wird nicht funktionieren, bis Sie Vorlage Inhalt klonen und fügen Sie sie zu einem vorhandenen Knoten in dem Dokument.

Wenn Sie bereit sind, jQuery zu verwenden, gibt es eine Problemumgehung. Sie können event delegation mithilfe der Methode jquery on verwenden, um Ereignisse an das übergeordnete Element zu binden.

etwas wie folgt aus:

$(this.container).on('click', '[data-price]', action); 

Was wird dies im Wesentlichen tun, dass jeder Klick, die von Kindern this.container perlt bis Eltern nach oben ausgelöst wird. Wenn es das Auswahlkriterium [data-price] erfüllt, wird die Aktion ausgelöst.

+0

Das jQuery 'on' * Trick * ist Magie. –

0

Wenn Sie mit den Zeilen "a" für Ihre Liste umgehen können, gibt Ihre document.getElementById (...) ein tatsächliches DOM-Element statt nur das DocumentFragment zurück, das es gerade tut. Das bedeutet, dass importNode (...) Ihnen echte DOM-Knoten zurückgibt, auf denen Sie addEventListener aufrufen und Ereignisse verknüpfen können!