When some html string added to DocumentFragment innerHTML
property, there are no children exists. But same action with Element created by createElement
show children. I created simple example for comparing innerHTML behavior for DocumentFragment and simple Element:
const fragment = document.createDocumentFragment();
const div = document.createElement('div')
fragment.innerHTML = "<i>Test</i>";
console.log('fragment children:', fragment.children); // empty
fragment.innerHTML = "<i><b>Test</b></i>";
console.log('fragment children:', fragment.children); // empty
div.innerHTML = "<i>Test</i>";
console.log('div children:', div.children) // has children
div.innerHTML = "<i><b>Test</b></i>";
console.log('div children:', div.children) // has children
But fragment can show children added by appendChild:
const span = document.createElement('span');
const fragment2 = document.createDocumentFragment();
fragment2.appendChild(span);
console.log('fragment children for appendChild', fragment2.children);
How to fix this weird DocumentFragment behavior ?
ADDITIONAL: I need DocumentFragment as temporary HTML container.
JSFiddle with reproducing the problem.
div
inherits from the HTMLElement
prototype, a child of the Node
prototype
DocumentFragment
inherits directly from the Node
prototype.
This is to say that div
has all of the Node methods and properties as well as all HTMLElement methods and properties.
DocumentFragment
only has Node methods and properties.
Though the Node prototype has the ability to have children, innerHTML
does not exist as an innate property. This is only available on HTMLElement
and its children (in this case HTMLDivElement
).
Assigning to innerHTML
on a child of a Node
prototype simply creates the property innerHTML
with your string as a value, but does nothing more.
Basically, elements have internal wiring that tells them what to do
when innerHTML
is assigned/updated. Nodes do not.
You can see this below:
const fragment = document.createDocumentFragment();
const div = document.createElement('div');
console.log("innerHTML in fragment: " + ('innerHTML' in fragment) );
console.log("innerHTML in element: " + ('innerHTML' in div) );
In order to use something as a container
and utilize innerHTML
you would really just need to create an element that contains what you're trying to add. You can use a number of different things like a template
Element or DOMParser
, but honestly the easiest is just to create a separate div
and classify it as a container
let container = document.createElement("div");
container.className = "container";
let div = document.createElement("div");
container.className = "child";
container.appendChild(div);
document.body.appendChild(container);
.container {
width: 100px;
height: 100px;
border: 1px solid red;
}
.child {
width: 10px;
height: 10px;
border: 1px solid green;
}