-1

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.

Sergio Ivanuzzo
  • 1,820
  • 4
  • 29
  • 59

1 Answers1

3

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;
}
zfrisch
  • 8,474
  • 1
  • 22
  • 34
  • thank you for the explanation. But this is not an answer. The question was: how to fix. So, it seems only way to fix this is to use `createElement` to create temporary dom ? – Sergio Ivanuzzo Nov 11 '19 at 22:51
  • @SergioIvanuzzo You're welcome. I can give you an alternative, sure, but what exactly are you "fixing" ? You simply need a container that allows for `innerHTML` ? I would think a `div` or a `section` would suffice. – zfrisch Nov 11 '19 at 22:54
  • additional: I need temporary container that allowable to apply querySelector on it – Sergio Ivanuzzo Nov 11 '19 at 23:03
  • great! Btw, when some operations performs on this container does it affects the DOM ? – Sergio Ivanuzzo Nov 11 '19 at 23:04
  • 1
    @SergioIvanuzzo When you append to the DOM, a clone of what you're appending is what's added. `appendChild` returns the added DOM nodes though. So in order to get a reference if you need to edit the DOM node, you can simply do something like `let editable = document.body.appendChild(container); editable.id = "newid";` – zfrisch Nov 11 '19 at 23:08
  • Glad I could help. If you have further questions please post them in new threads, thanks! – zfrisch Nov 11 '19 at 23:10