1

I am working inside of a DocumentFragment, and am attempting to insert HTML into it. We know that that a DocumentFragment does not have an innerHTML setter, so I attempted to insert a temporary node into the DocumentFragment and insert HTML after it using insertAdjacentHTML. I would then remove the temporary element, and be left with a fragment with the DOM I wanted.

Example: (error is on purpose)

var fragment = document.createDocumentFragment();
var temporaryElement = fragment.appendChild(document.createElement('div'));

// Before we move on.. I can see that the `temporaryElement` does have a parent
console.log(temporaryElement.parentNode.nodeType);

// The following throws an error...
temporaryElement.insertAdjacentHTML('afterend', '<div>Some crazy custom HTML..</div>');

fragment.removeChild(temporaryElement);

I can clearly see that there is a parentNode for the temporary element, so why would I get this error?

Supersharp
  • 29,002
  • 9
  • 92
  • 134
KevBot
  • 17,900
  • 5
  • 50
  • 68
  • The parent node is of type `Node.DOCUMENT_FRAGMENT_NODE` (the console shows 11, which matches that constant), which is apparently not a valid parent for running `insertAdjacentHTML`. See also [MDN's Browser Compatibility table](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment#Browser_compatibility), where it shows that ParentNode methods are unavailable in all browsers... – Heretic Monkey Feb 27 '17 at 19:34
  • you can append another fragment, that way you don't have to remove anything later. see http://stackoverflow.com/questions/9284117/inserting-arbitrary-html-into-a-documentfragment/25214113#25214113 for a handy helper – dandavis Feb 27 '17 at 19:43

2 Answers2

5

You can:

  1. Create a <template> element,
  2. Add string content via its innerHTML property,
  3. Get a DocumentFragment from its content property.

//Use a template
var template = document.createElement( 'template' )
template.innerHTML = '<td>Hello<td>World'

//Get the document fragment
var fragment = template.content
Row.appendChild( fragment )
<table>
  <tr id=Row></tr>
</table>
Supersharp
  • 29,002
  • 9
  • 92
  • 134
  • 2
    I appreciate that you addressed the concern of adding in elements that need certain parent tags (`td`). I did end up going this route, but because template tags are not supported in IE11 I had to do some fallbacks. Thanks for the help! If you're interested, this is [what I ended up with](https://github.com/kevinokerlund/html-fragment/blob/master/src/html-fragment.js) – KevBot Mar 01 '17 at 20:28
-1

So I'm pretty sure you want to end up with a parsed div, right? So to do that you would do this.

var fragment = document.createElement("div");
fragment.innerHTML = "Some crazy custom HTML..";

//This will output exactly what your code should do
console.log(fragment);
Mason Wright
  • 357
  • 1
  • 3
  • 11
  • Good idea, but this won't work if the HTML is `Data`. The div will drop the tags, and leave you with only the text node: `"Data"`. This is why it needs to be directly placed inside of a fragment. – KevBot Feb 27 '17 at 20:16
  • @KevBot Then I would try document.createElement with the td's then appendChild them to the fragment – Mason Wright Feb 27 '17 at 20:19