12

我正在使用<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 );

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

4

2 回答 2

10

在您使用 document.importNode “激活”模板之前,它的内容是不属于 DOM 的惰性节点。

根据 addEventListener 文档:

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

因此,在您克隆模板内容并将它们添加到文档中的现有节点之前,在您的示例中添加事件侦听器将不起作用。

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

像这样的东西:

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

这基本上会做什么,任何从子级触发的点击this.container都会冒泡到父级。如果它满足[data-price]动作的选择器标准,就会触发它。

于 2015-10-04T11:05:15.750 回答
0

如果您可以使用 a 作为列表行,那么您的 document.getElementById(...) 将返回一个实际的 DOM 元素,而不仅仅是它现在所做的 DocumentFragment。这意味着 importNode(...) 将返回真正的 DOM 节点,您可以在这些节点上调用 addEventListener 并连接事件!

于 2017-11-21T07:24:04.347 回答