是否可以将单击事件附加到文档片段?

时间:2015-03-14 10:35:43

标签: javascript

我尝试过:

// 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);
});

此示例不起作用。事件未被触发。

有没有办法将点击事件附加到文档片段,或者根本不可能?

3 个答案:

答案 0 :(得分:8)

在这种情况下,click事件将不起作用,因为文档片段未附加到DOM结构。以下是documentation对此的说法:

  

各种其他方法可以将文档片段作为参数(例如,任何节点接口方法,例如Node.appendChildNode.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)
    }
}