我尝试过:
// creating elements
var container = document.createDocumentFragment();
var headline = document.createElement('h1');
headline.innerHTML = 'This is a headline.';
// attaching to DOM
container.appendChild(headline);
document.body.appendChild(container);
// attaching click event
container.addEventListener('click', function () {
console.log(arguments);
});
此示例不起作用。事件未被触发。
有没有办法将点击事件附加到文档片段,或者根本不可能?
答案 0 :(得分:8)
在这种情况下,click事件将不起作用,因为文档片段未附加到DOM结构。以下是documentation对此的说法:
各种其他方法可以将文档片段作为参数(例如,任何节点接口方法,例如Node.appendChild和Node.insertBefore),在这种情况下,片段的子节点被追加或插入,而不是片段本身。
所以“片段的孩子被附加,而不是片段本身”。这意味着绑定到片段的click事件几乎没用,因为在DOM之外无法访问点击。
答案 1 :(得分:2)
有两点使您的代码无法正常工作
DocumentFragment
首先,如@dfsq所说,container
的值为DocumentFragment
。稍后当您调用appendChild
时,DocumentFragment
的内容将移至DOM中,但片段本身不会。这意味着事件监听器是“落后的”,永远不会被点击触发。
解决方案是将事件侦听器附加到container
的子级之一,例如headline
:
headline.addEventListener('click', ...
通常您没有直接的参考文献like if you're working with templates and .cloneNode
。在许多情况下,片段仅包含一个元素,因此使用container.firstElementChild
是一个好方法。如果您的片段更复杂,则可能需要使用.querySelector
或类似的内容。
container.appendChild(headline);
container.firstElementChild.addEventListener('click', // ...
DocumentFragment
和.appendChild
第二,当您调用document.body.appendChild
the contents of the DocumentFragment
are moved into the DOM时,它不在片段中。该片段不保留引用。这个想法是一个节点不能有两个父节点。这意味着,在您调用addEventListener
时,没有任何事件发生的节点!
解决方案是在调用.appendChild
之前,在事件监听器之前。
将这两者放在一起可以实现以下实现:
// creating elements
var container = document.createDocumentFragment();
var headline = document.createElement('h1');
headline.innerHTML = 'This is a headline.';
// attaching click event
headline.addEventListener('click', function () {
console.log('click happened!');
});
// attaching to DOM
container.appendChild(headline);
document.body.appendChild(container);
答案 2 :(得分:0)
有一个示例说明如何创建片段获取 html 组件之一并在其上附加事件...
function createFragmentWithEvent(){
let html = `
<div style="display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; padding: 5px;">
<img style="width: 40px; height: 40px; " src="${value.profilPicture_}"></img>
<div style="display: flex; flex-direction: column; font-size: .85em; padding-left: 8px;">
<span>${value._id}</span>
<span>${value.email_}</span>
</div>
</div>
<paper-button style="font-size:.65em; width: 20px; align-self: flex-end;" id="${value._id}_invite_btn">Invite</paper-button>
</div>`
let range = document.createRange()
let fragment = range.createContextualFragment(html)
let inviteBtn = fragment.getElementById(value._id + "_invite_btn")
inviteBtn.onclick = ()=>{
console.log("----> invite ", value)
}
}