将事件侦听器添加到从template标签克隆的元素中 [英] Adding event listeners to elements cloned from the template tag

查看:142
本文介绍了将事件侦听器添加到从template标签克隆的元素中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用<template>标签创建许多DOM元素(每个元素具有相同的HTML结构):

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

...和几行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 );

我想在克隆的元素上添加一些事件侦听器.我从互联网上找不到任何东西,累了自己的几件事,例如:

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

...这些都不起作用.我可以简单地做些类似的事情:

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

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

...但是我想知道是否还有另一种更简单的方法,类似于对我不起作用的方法.

解决方案

在使用document.importNode激活"模板之前,其内容是不属于DOM的惰性节点.

根据addEventListener文档:

事件目标可以是文档中的元素,文档本身, 窗口或支持事件的任何其他对象(例如 XMLHttpRequest).

因此,在克隆模板内容并将添加到文档中的现有节点之前,无法在示例中添加事件侦听器.

如果您准备使用jQuery,则有一种解决方法.您可以使用事件委托,方法是使用jquery on方法将事件绑定到父元素.

类似这样的东西:

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

从本质上讲,从this.container的子级触发的任何点击都会冒泡直到父级.如果满足,则将触发[data-price]操作的选择器条件.

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.

解决方案

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.

这篇关于将事件侦听器添加到从template标签克隆的元素中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆