Adding event listeners to elements cloned from the template tag

只谈情不闲聊 提交于 2019-12-19 16:13:53

问题


I am creating a lot of DOM elements (each has the same HTML structure) with the <template> tag:

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

... and a few lines of 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 );

I would love to add some event listeners on the cloned elements. I could not find nothing from internet and tired a couple of things my self, like:

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

... none of these worked. I could simply do something like:

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

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

... but I wonder if there is another, simpler way similar to those that has not worked for me.


回答1:


Until you 'activate' template using document.importNode, its content are inert nodes which are not part of DOM.

As per addEventListener docs:

The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest).

Therefore adding event listeners in your example won't work until you clone template contents and add them to an existing node in document.

If you are ready to use jQuery, there is a workaround. You can use event delegation using jquery on method to bind events to parent element.

something like this:

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

What this will essentially do that any click which is being triggered from children of this.container will bubble up till parent. If it satisfies the selector criteria of [data-price] action will triggered on it.




回答2:


If you can get around using a for your list rows, then your document.getElementById(...) will return an actual DOM element instead of just the DocumentFragment that it does right now. This means that importNode(...) will return you real DOM nodes on which you can call addEventListener and hook up events!



来源:https://stackoverflow.com/questions/30968322/adding-event-listeners-to-elements-cloned-from-the-template-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!