Is it possible to attach a click event to a document fragment?
The click event will not work in this case because document fragment is not appended to DOM structure. Here is what documentation says about it:
Various other methods can take a document fragment as an argument (e.g., any Node interface methods such as Node.appendChild and Node.insertBefore), in which case the children of the fragment are appended or inserted, not the fragment itself.
So "children of the fragment are appended, not fragment itself". It means that click event bound to fragment is pretty much useless, because being outside of the DOM it's not reachable for clicks.
There are two things preventing your code from working
Events and DocumentFragment
First, as @dfsq said, the value of container
is a DocumentFragment
. When you call appendChild
later, the contents of the DocumentFragment
are moved into the DOM, but the fragment itself is not. That means the event listener is "left behind", and won't ever be triggered by a click.
The solution is to attach the event listener to one of the children of container
, like headline
:
headline.addEventListener('click', ...
Often you don't have a direct reference, like if you're working with templates and .cloneNode
. In many cases the fragment only contains one element, so using container.firstElementChild
is a good way to go. If your fragment were more complex, you might need to use .querySelector
or something similar.
container.appendChild(headline);
container.firstElementChild.addEventListener('click', // ...
DocumentFragment
and .appendChild
Second, when you call document.body.appendChild
the contents of the DocumentFragment
are moved into the DOM, and out of the fragment. The fragment doesn't retain a reference. The idea is that a node can't have two parents. That means that by the time you call addEventListener
, there aren't any nodes for events to happen to!
The solution is to attach the event listener before calling .appendChild
.
Solution
Putting these two together gives the following implementation:
// 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);