Ruft die Zeichenfolgendarstellung eines DOM-Knotens ab

96

Javascript: Ich habe die DOM-Darstellung eines Knotens (Elements oder Dokuments) und suche nach der Zeichenfolgendarstellung davon. Z.B,

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

sollte ergeben:

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

Ich habe das starke Gefühl, dass mir etwas trivial Einfaches fehlt, aber ich finde einfach keine Methode, die in IE, FF, Safari und Opera funktioniert. Daher ist OuterHTML keine Option.

Boldewyn
quelle
4
Mit vermutlich Version 11 unterstützt Firefox auch OuterHTML: bugzilla.mozilla.org/show_bug.cgi?id=92264
Boldewyn
1
Derzeit unterstützen IE, FF, Safari, Chrome und Opera alle OuterHTML, siehe developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
Wangf
1
Ja, es ist jetzt (seit 2009) eine triviale Aufgabe geworden :)
Boldewyn
Ja, definitiv OuterHTML
Neaumusic

Antworten:

133

Sie können einen temporären übergeordneten Knoten erstellen und dessen innerHTML-Inhalt abrufen:

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: Siehe Antwort unten über OuterHTML. el.outerHTML sollte alles sein, was benötigt wird.

CMS
quelle
1
Autsch. So einfach ... Nur ein kleiner Hinweis: Wenn ich möchte, dass das gesamte Dokument "stringifiziert" wird, kann ich dieselbe Methode mit document.documentElement verwenden (Anwendungsfall: AJAX-Anforderungen). Vielleicht könnten Sie das in die Antwort aufnehmen?
Boldewyn
3
@ Boldewyn: Kannst du das Ganze document.documentElementin ein Div einfügen ? Heiliger Mist ....
Roatin Marth
Einfach, wie die Hölle ... +1 Schade, documentFragment unterstützt innerHTML nicht
Lajos Meszaros
30
OuterHTML ist die Antwort
Neaumusic
3
Vergessen Sie nicht, Ihre zu klonen, elementbevor Sie sie hinzufügen, tmpda sie beim Hinzufügen tmpentfernt wird document.
Olcay Ertaş
44

Was Sie suchen, ist 'OuterHTML', aber wir brauchen einen Fallback, da es nicht mit alten Browsern kompatibel ist.

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

Mein jQuery-Plugin finden Sie hier: Holen Sie sich das äußere HTML des ausgewählten Elements

gtournie
quelle
Firefox wurde outerHTMLin Version 11 hinzugefügt , nachdem ich die Frage gestellt hatte. Das war damals also keine Option. Ich habe meine Frage sogar mit einem entsprechenden Kommentar aktualisiert, wenn Sie genau hinschauen.
Boldewyn
Dieses Recht, weil Sie Element-IDs und andere Attribute löschen, wenn Sie verwendeninnerHtml
Sergei
1
@ SergeyPanfilov: Ich habe nichts gelöscht, weil ich den Knoten vor dem Aufruf in ein leeres Div gewickelt habe innerHTML. )
Gtournie
3
2015 würde ich sagen, dass dies mit Abstand die beste Antwort ist.
ACK_stoverflow
Ja, bis heute unterstützen nur sehr alte (IE> 10, Safari> 7, wirklich alte FF, Chrome) und / oder obskure Browser (Opera Mini) das outerHTMLAttribut nicht. Siehe auch caniuse.com/#feat=xml-serializer
Gert Sønderby
20

Ich glaube nicht, dass Sie dafür ein kompliziertes Skript benötigen. Benutz einfach

get_string=(el)=>el.outerHTML;
Shishir Arora
quelle
dies ist die beste Antwort
Avraham
15

Unter FF können Sie das XMLSerializerObjekt verwenden, um XML in eine Zeichenfolge zu serialisieren. IE gibt Ihnen eine xmlEigenschaft eines Knotens. Sie können also Folgendes tun:

function xml2string(node) {
   if (typeof(XMLSerializer) !== 'undefined') {
      var serializer = new XMLSerializer();
      return serializer.serializeToString(node);
   } else if (node.xml) {
      return node.xml;
   }
}
Bryan Kyle
quelle
Zu Ihrer Information .xmlfunktioniert nicht auf DOM-Knoten (wie bei Knoten auf der aktuellen Seite). Es funktioniert nur auf XML-DOM-Dokumentknoten.
Crescent Fresh
Und outerHTMLfunktioniert umgekehrt nicht auf XML-DOM-Dokumentknoten. Es funktioniert nur auf DOM-Knoten (wie bei Knoten auf der aktuellen Seite). Gute Konsistenz dort würde ich sagen.
Crescent Fresh
7

Verwenden Sie Element # OuterHTML:

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

console.log(el.outerHTML);

Es kann auch zum Schreiben von DOM-Elementen verwendet werden. Aus Mozillas Dokumentation:

Das OuterHTML-Attribut der Element-DOM-Schnittstelle erhält das serialisierte HTML-Fragment, das das Element einschließlich seiner Nachkommen beschreibt. Es kann so eingestellt werden, dass das Element durch Knoten ersetzt wird, die aus der angegebenen Zeichenfolge analysiert wurden.

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

Reiches Apodaca
quelle
3

Verwenden Sie element.outerHTML, um eine vollständige Darstellung des Elements einschließlich der äußeren Tags und Attribute zu erhalten.

Pavel V.
quelle
1

Wenn Ihr Element übergeordnet ist

element.parentElement.innerHTML
Vincnetas
quelle
2
Danke für die Antwort! Leider wurde das schon vorgeschlagen, aber der Antwortende hat die Antwort gelöscht. Das Problem ist, dass das übergeordnete Element möglicherweise viel mehr Markups enthält als gewünscht. Denken Sie an OuterHTML für eine einzelne <li>in einer Liste.
Boldewyn
1

Versuchen

new XMLSerializer().serializeToString(element);
Alex Popa
quelle
Vielen Dank für den Vorschlag, aber genau das hat Bryan Kale in seiner Antwort vorgeschlagen.
Boldewyn
1

Ich habe festgestellt, dass ich für meine Anwendungsfälle nicht immer die gesamte äußere HTML möchte. Viele Knoten haben einfach zu viele Kinder, um sie anzuzeigen.

Hier ist eine Funktion (minimal in Chrome getestet):

/**
 * 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

Aaron
quelle
0

Ich habe viel Zeit damit verschwendet, herauszufinden, was falsch ist, wenn ich DOMElements mit dem Code in der akzeptierten Antwort durchlaufe. Das hat bei mir funktioniert, sonst verschwindet jedes zweite Element aus dem Dokument:

_getGpxString: function(node) {
          clone = node.cloneNode(true);
          var tmp = document.createElement("div");
          tmp.appendChild(clone);
          return tmp.innerHTML;
        },
Balagan
quelle
1
Ich gehe nicht auf die Nerven, wenn ich vermute, dass Sie hier ein anderes Problem haben. Beachten Sie , dass die obige Lösung entfernt das ursprüngliche Element aus dem DOM. Wenn Sie also eine Live- Sammlung wie diese verwenden document.getElementsByTagName(), ändert sich diese Sammlung in der Mitte der forSchleife, sodass jedes zweite Element übersprungen wird.
Boldewyn
-1

bei Verwendung reagieren:

const html = ReactDOM.findDOMNode(document.getElementsByTagName('html')[0]).outerHTML;
victorkurauchi
quelle
.outerHTMList nicht reaktionsspezifisch; Es ist ein DOM-Standard. Schauen Sie sich die Antwort von @Rich Apodaca an.
Chharvey
ja ... der Punkt von Interesse (wenn ich reagiere) auf meine Antwort war reactdom.findDOMNode()..., nicht der .outerHTML, aber danke für die Position.
victorkurauchi