Get the string representation of a DOM node

148,113

Solution 1

You can create a temporary parent node, and get the innerHTML content of it:

var el = document.createElement("p");
el.appendChild(document.createTextNode("Test"));

var tmp = document.createElement("div");
tmp.appendChild(el);
console.log(tmp.innerHTML); // <p>Test</p>

EDIT: Please see answer below about outerHTML. el.outerHTML should be all that is needed.

Solution 2

What you're looking for is 'outerHTML', but wee need a fallback coz it's not compatible with old browsers.

var getString = (function() {
  var DIV = document.createElement("div");

  if ('outerHTML' in DIV)
    return function(node) {
      return node.outerHTML;
    };

  return function(node) {
    var div = DIV.cloneNode();
    div.appendChild(node.cloneNode(true));
    return div.innerHTML;
  };

})();

// getString(el) == "<p>Test</p>"

You'll find my jQuery plugin here: Get selected element's outer HTML

Solution 3

I dont think you need any complicated script for this. Just use

get_string=(el)=>el.outerHTML;

Solution 4

Under FF you can use the XMLSerializer object to serialize XML into a string. IE gives you an xml property of a node. So you can do the following:

function xml2string(node) {
   if (typeof(XMLSerializer) !== 'undefined') {
      var serializer = new XMLSerializer();
      return serializer.serializeToString(node);
   } else if (node.xml) {
      return node.xml;
   }
}

Solution 5

Use Element#outerHTML:

var el = document.createElement("p");
el.appendChild(document.createTextNode("Test"));

console.log(el.outerHTML);

It can also be used to write DOM elements. From Mozilla's documentation:

The outerHTML attribute of the element DOM interface gets the serialized HTML fragment describing the element including its descendants. It can be set to replace the element with nodes parsed from the given string.

https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML

Share:
148,113
Boldewyn
Author by

Boldewyn

Boldewyn is the name of the donkey in German fables (at least, the ones from Goethe). Despite its bad name, a donkey is an animal with its own head and quite a portion of wit. As someone pointed out once, if you say to a horse to jump down that abyss, it would happily do so, whereas the donkey would give you a kick where you deserve it to. And someone else pointed out, that laziness is a core requirement for a good developer...

Updated on February 24, 2021

Comments

  • Boldewyn
    Boldewyn about 3 years

    Javascript: I have the DOM representation of a node (element or document) and I'm looking for the string representation of it. E.g.,

    var el = document.createElement("p");
    el.appendChild(document.createTextNode("Test"));
    

    should yield:

    get_string(el) == "<p>Test</p>";
    

    I have the strong feeling, that I'm missing something trivially simple, but I just don't find a method that works in IE, FF, Safari and Opera. Therefore, outerHTML is no option.

  • Boldewyn
    Boldewyn over 14 years
    Ouch. So simple... Just a little note: If I want the whole document "stringified", I can use the same method with document.documentElement (usecase: AJAX requests). Perhaps you could incorporate that in the answer?
  • Crescent Fresh
    Crescent Fresh over 14 years
    FYI .xml doesn't work on DOM nodes (as in nodes in the current page). It only works on XML DOM document nodes.
  • Crescent Fresh
    Crescent Fresh over 14 years
    And conversely, outerHTML doesn't work on XML DOM document nodes. It only works on DOM nodes (as in nodes in the current page). Good consistency there I'd say.
  • Roatin Marth
    Roatin Marth over 14 years
    @Boldewyn: you can append the entire document.documentElement into a div? Holy crap....
  • Lajos Mészáros
    Lajos Mészáros almost 11 years
    Simple, as hell... +1 Too bad documentFragment does not support innerHTML
  • Boldewyn
    Boldewyn over 10 years
    Firefox added outerHTML in version 11, after I asked the question. So that wasn't an option back then. I even updated my question with an appropriate comment, if you look closely.
  • Boldewyn
    Boldewyn about 10 years
    I don't go out on a limb, when I suppose, that you have a different problem here. Note, that the above solution removes the original element from the DOM. So, when you use a live collection like document.getElementsByTagName(), that collection will change mid-for-loop, hence the skipping of every second element.
  • Boldewyn
    Boldewyn over 9 years
    Thanks for the answer! Unfortunately that was already suggested, but the answerer deleted the answer. The problem is, that the parent might contain a lot more markup than wanted. Think of outerHTML for a single <li> in a list.
  • Sergei Panfilov
    Sergei Panfilov almost 9 years
    This right, coz you drop element id's and other attrs if use innerHtml
  • gtournie
    gtournie almost 9 years
    @SergeyPanfilov: I didn't drop anything because I wrapped the node in an empty div before calling innerHTML ; )
  • JellicleCat
    JellicleCat almost 9 years
    This appears to omit the elements' attributes, like class. Any way to get those in the output?
  • neaumusic
    neaumusic almost 9 years
    outerHTML is the answer
  • ACK_stoverflow
    ACK_stoverflow almost 9 years
    In 2015, I would say this is far and away the best answer.
  • Gert Sønderby
    Gert Sønderby over 8 years
    I had an array of nodes (from jQuery's parseHTML function), and was able to simply map across them with a function extracting outerHTML, and then join the resulting array of strings with no separator. The result was an HTML string equivalent to what I had put in, but containing the subsequent changes I had applied to the nodes.
  • Gert Sønderby
    Gert Sønderby over 8 years
    Yeah, as of today, only very old (IE>10,Safari >7, truly ancient FF, Chrome) and/or obscure browsers (Opera Mini) do not support the outerHTML attribute. See also caniuse.com/#feat=xml-serializer
  • Olcay Ertaş
    Olcay Ertaş over 7 years
    Don't forget to clone your element before adding it to tmp becouse when you add it to tmp, it will be removed from document.
  • WebBrother
    WebBrother over 6 years
    This have to be best answer: stackoverflow.com/a/35913488/2179748
  • chharvey
    chharvey over 6 years
    .outerHTML is not React-specific; it is a DOM standard. Check out @Rich Apodaca’s answer.
  • victorkurauchi
    victorkurauchi over 6 years
    yes... the point of interest (if using react) on my answer was reactdom.findDOMNode()... , not the .outerHTML, but thanks for the position.
  • Wa.
    Wa. about 6 years
    Simply document.documentElement.outerHTML; if you don't care about old browsers.
  • k33g_org
    k33g_org about 6 years
    if you want the tag too, outerHTML is the correct answer
  • Boldewyn
    Boldewyn over 5 years
    Thanks for the suggestion, but that is exactly what Bryan Kale suggested in his answer.
  • Avraham
    Avraham almost 5 years
    this is the best answer
  • Eric
    Eric almost 3 years
    Today we can simply use outerHTML