Obtenir la représentation sous forme de chaîne d'un nœud DOM


97

Javascript: J'ai la représentation DOM d'un nœud (élément ou document) et je cherche la représentation sous forme de chaîne de celui-ci. Par exemple,

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

devrait céder:

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

J'ai le sentiment fort, qu'il me manque quelque chose de trivialement simple, mais je ne trouve tout simplement pas de méthode qui fonctionne dans IE, FF, Safari et Opera. Par conséquent, externalHTML n'est pas une option.


4
Avec vraisemblablement la version 11, Firefox prend également en charge externalHTML
Boldewyn

1
Pour l'instant, il semble que IE, FF, Safari, Chrome, Opera prennent tous en charge le
HTML externe

1
Oui, c'est maintenant (depuis 2009, c'est-à-dire) devenu une tâche triviale :)
Boldewyn

Oui, certainement
externeHTML

Réponses:


134

Vous pouvez créer un nœud parent temporaire et en obtenir le contenu innerHTML:

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: Veuillez voir la réponse ci-dessous à propos de externalHTML. el.outerHTML devrait être tout ce qui est nécessaire.


1
Aie. Si simple ... Juste une petite note: si je veux que le document entier soit "stringifié", je peux utiliser la même méthode avec document.documentElement (cas d'utilisation: requêtes AJAX). Peut-être pourriez-vous intégrer cela dans la réponse?
Boldewyn

3
@Boldewyn: vous pouvez ajouter le tout document.documentElementdans un div? Holy crap ....
Roatin Marth

Simple, as hell ... +1 Trop mauvais documentFragment ne prend pas en charge innerHTML
Lajos Meszaros

30
externalHTML est la réponse
neaumusic

3
N'oubliez pas de cloner votre elementavant de l'ajouter, tmpcar lorsque vous l'ajouterez tmp, il sera supprimé document.
Olcay Ertaş

45

Ce que vous recherchez, c'est «externalHTML», mais nous avons besoin d'une solution de secours car elle n'est pas compatible avec les anciens navigateurs.

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>"

Vous trouverez mon plugin jQuery ici: Obtenez le HTML externe de l'élément sélectionné


Firefox ajouté outerHTMLdans la version 11, après avoir posé la question. Ce n'était donc pas une option à l'époque. J'ai même mis à jour ma question avec un commentaire approprié, si vous regardez attentivement.
Boldewyn

Ce droit, vous coz de déposer id élément et autres attrs si l' utilisationinnerHtml
Sergei Panfilov

1
@SergeyPanfilov: Je n'ai rien laissé tomber parce que j'ai enveloppé le nœud dans un div vide avant d'appeler innerHTML; )
gtournie

3
En 2015, je dirais que c'est de loin la meilleure réponse.
ACK_stoverflow

Oui, à ce jour, seuls les navigateurs très anciens (IE> 10, Safari> 7, vraiment ancien FF, Chrome) et / ou obscurs (Opera Mini) ne prennent pas en charge l' outerHTMLattribut. Voir aussi caniuse.com/#feat=xml-serializer
Gert Sønder du

20

Je ne pense pas que vous ayez besoin d'un script compliqué pour cela. Juste utiliser

get_string=(el)=>el.outerHTML;

c'est la meilleure réponse
Avraham

15

Sous FF, vous pouvez utiliser l' XMLSerializerobjet pour sérialiser XML en une chaîne. IE vous donne une xmlpropriété d'un nœud. Vous pouvez donc faire ce qui suit:

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

FYI .xmlne fonctionne pas sur les nœuds DOM (comme dans les nœuds de la page actuelle). Cela ne fonctionne que sur les nœuds de document XML DOM.
Crescent Fresh

Et inversement, outerHTMLne fonctionne pas sur les nœuds de document XML DOM. Cela ne fonctionne que sur les nœuds DOM (comme dans les nœuds de la page actuelle). Bonne cohérence là je dirais.
Crescent Fresh

7

Utilisez l'élément # externalHTML:

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

console.log(el.outerHTML);

Il peut également être utilisé pour écrire des éléments DOM. De la documentation de Mozilla:

L'attribut externalHTML de l'interface DOM d'élément obtient le fragment HTML sérialisé décrivant l'élément, y compris ses descendants. Il peut être défini pour remplacer l'élément par des nœuds analysés à partir de la chaîne donnée.

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


3

Utilisez element.outerHTML pour obtenir une représentation complète de l'élément, y compris les balises externes et les attributs.


1

Si votre élément a un parent

element.parentElement.innerHTML

2
Merci d'avoir répondu! Malheureusement, cela a déjà été suggéré, mais le répondant a supprimé la réponse. Le problème est que le parent peut contenir beaucoup plus de balisage que souhaité. Pensez à externalHTML pour un seul <li>dans une liste.
Boldewyn

1

Essayer

new XMLSerializer().serializeToString(element);

Merci pour la suggestion, mais c'est exactement ce que Bryan Kale a suggéré dans sa réponse.
Boldewyn

1

J'ai trouvé que pour mes cas d'utilisation, je ne veux pas toujours l'intégralité du HTML externe. De nombreux nœuds ont juste trop d'enfants à afficher.

Voici une fonction (testée au minimum dans Chrome):

/**
 * Stringifies a DOM node.
 * @param {Object} el - A DOM node.
 * @param {Number} truncate - How much to truncate innerHTML of element.
 * @returns {String} - A stringified node with attributes
 *                     retained.
 */
function stringifyEl(el, truncate) {
    var truncateLen = truncate || 50;
    var outerHTML = el.outerHTML;
    var ret = outerHTML;
    ret = ret.substring(0, truncateLen);

    // If we've truncated, add an elipsis.
    if (outerHTML.length > truncateLen) {
      ret += "...";
    }
    return ret;
}

https://gist.github.com/kahunacohen/467f5cc259b5d4a85eb201518dcb15ec


0

J'ai perdu beaucoup de temps à déterminer ce qui ne va pas lorsque j'itère dans DOMElements avec le code dans la réponse acceptée. C'est ce qui a fonctionné pour moi, sinon chaque deuxième élément disparaît du document:

_getGpxString: function(node) {
          clone = node.cloneNode(true);
          var tmp = document.createElement("div");
          tmp.appendChild(clone);
          return tmp.innerHTML;
        },

1
Je ne me dis pas, quand je suppose, que vous avez un problème différent ici. Notez que la solution ci-dessus supprime l'élément d'origine du DOM. Ainsi, lorsque vous utilisez une collection live comme document.getElementsByTagName(), cette collection changera à mi- forboucle, d'où le saut de chaque deuxième élément.
Boldewyn

-1

si vous utilisez react:

const html = ReactDOM.findDOMNode(document.getElementsByTagName('html')[0]).outerHTML;

.outerHTMLn'est pas spécifique à React; c'est un standard DOM. Découvrez la réponse de @Rich Apodaca.
chharvey

oui ... le point d'intérêt (si vous utilisez react) sur ma réponse était reactdom.findDOMNode()..., pas le .outerHTML, mais merci pour la position.
victorkurauchi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.