6

I'm adding textnodes to a documentFragment like this:

var foo = document.createDocumentFragment();
var someText = "Hello World";
foo.appendChild(document.createTextNode(someText));

This works fine, but sometimes I'm being passed "text" which includes inline links like this:

var someOtherText = "Hello <a href='www.world.com'>World</a>";

Which in my handler is converted to hardcoded text instead of a link.

Question:
How do I append an HTML string like the above into a documentFragment? If I'm not using textNodes can this be done using appendChild?

Havvy
  • 1,471
  • 14
  • 27
frequent
  • 27,643
  • 59
  • 181
  • 333
  • 1
    You could create a div-tag and use innerHTML. – some Nov 12 '13 at 12:51
  • can't because it needs to run through my handler which only creates documentFragments – frequent Nov 12 '13 at 12:53
  • Let your handler create a div internally, assign the string to innerHTML, and then move the created nodes to the fragment. – some Nov 12 '13 at 12:55
  • hm. let me try if this works. – frequent Nov 12 '13 at 12:57
  • Create div, append div, use outerHTML. – CBroe Nov 12 '13 at 12:58
  • @CBroe How is outerHTML supposed to help when it returns a string, and you can't append a string to a fragment? – some Nov 12 '13 at 13:08
  • Does innerHTML only _return_ strings? No. So why are you assuming that was the case for outerHTML …? – CBroe Nov 12 '13 at 13:13
  • @CBroe [outerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element.outerHTML) and [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML) returns a *string*. A string that could be `Stack overflow` but that is still a *string*. Proof: `var a=document.createElement('div'); a.innerHTML = "Stack overflow"; console.log('The types are: %s %s', typeof a.innerHTML, typeof a.outerHTML);`. What are the types? string and string. – some Nov 12 '13 at 13:23
  • @CBroe Ok, I misunderstood you. Both innerHTML and outerHTML can be used to both SET and GET the value (as a string). However, a documentFragment (that the question is about) can be inserted into another element. Could you show some code where you use outerHTML and where your return a documentFragent? – some Nov 12 '13 at 13:36
  • I was thinking of pretty much the same as your approach – create a DIV, append that to the fragment, and then replace the div by div.outerHTML="…" (would save appending child elements in the loop) … but that does not seem to work cross-browser, so your approach looks to be more solid. – CBroe Nov 12 '13 at 13:38

3 Answers3

15

Create a template-element, add the text with .innerHTML and get a documentFragment with the content-property:

function stringToFragment(string) {
  const temp = document.createElement('template');
  temp.innerHTML = string;
  return temp.content;
}

Now you can create a documentFragment from a string, and you can even append a documentFragment to a documentFragment:

const frag = stringToFragment('<div>Hello</div>');
frag.append(stringToFragment('<div>Stackoverflow</div>'));
gouessej
  • 3,640
  • 3
  • 33
  • 67
some
  • 48,070
  • 14
  • 77
  • 93
5
document.createRange().createContextualFragment("<span>Hello World!</span>");

It returns a DocumentFragment.

Support IE >= 9

EDIT:

recent versions Safari seems to fail with the short way, here is a little bit longer but working way:

var range = document.createRange();
range.selectNode(document.body); // Select the body cause there is always one (documentElement fail...)

var fragment = range.createContextualFragment("<span>Hello World!</span>");
Jordan
  • 3,776
  • 3
  • 22
  • 28
1

This may works:

var foo = document.createDocumentFragment();
var someText = 'Hello <a href="www.world.com">World</a>';
var item = document.createElement('span');
item.innerHTML = someText
foo.appendChild(item);
document.body.appendChild(foo);