Ottieni la rappresentazione di stringa di un nodo DOM


96

Javascript: ho la rappresentazione DOM di un nodo (elemento o documento) e sto cercando la rappresentazione di stringa di esso. Per esempio,

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

dovrebbe produrre:

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

Ho la forte sensazione che mi manchi qualcosa di banalmente semplice, ma non trovo un metodo che funzioni in IE, FF, Safari e Opera. Pertanto, outerHTML non è un'opzione.


4
Con presumibilmente la versione 11 Firefox supporta anche l'
hTML esterno

1
Per ora, sembra che IE, FF, Safari, Chrome, Opera supportino tutti outerHTML, vedere developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
wangf

1
Sì, ora (dal 2009, cioè) è diventato un compito banale :)
Boldewyn

Sì, decisamente outerHTML
neaumusic

Risposte:


133

Puoi creare un nodo genitore temporaneo e ottenerne il contenuto 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>

MODIFICA: vedere la risposta di seguito su outerHTML. el.outerHTML dovrebbe essere tutto ciò che è necessario.


1
Ahia. Così semplice ... Solo una piccola nota: se voglio che l'intero documento "stringa", posso usare lo stesso metodo con document.documentElement (caso d'uso: richieste AJAX). Forse potresti incorporarlo nella risposta?
Boldewyn

3
@ Boldewyn: puoi aggiungere l'intero document.documentElementin un div? Santo
cielo

Semplice, come l'inferno ... +1 Peccato documentoFragment non supporta innerHTML
Lajos Meszaros

30
outerHTML è la risposta
neaumusic

3
Non dimenticare di clonare il tuo elementprima di aggiungerlo tmpperché quando lo aggiungi a tmp, verrà rimosso da document.
Olcay Ertaş,

44

Quello che stai cercando è "outerHTML", ma abbiamo bisogno di un fallback perché non è compatibile con i vecchi browser.

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

Troverai il mio plugin jQuery qui: Ottieni l'HTML esterno dell'elemento selezionato


Firefox aggiunto outerHTMLnella versione 11, dopo che ho posto la domanda. Quindi quella non era un'opzione allora. Ho persino aggiornato la mia domanda con un commento appropriato, se guardi da vicino.
Boldewyn

Questo è giusto, perché se usi gli ID degli elementi e altri attributiinnerHtml
Sergei Panfilov,

1
@SergeyPanfilov: non ho rilasciato nulla perché ho avvolto il nodo in un div vuoto prima di chiamare innerHTML; )
gtournie

3
Nel 2015, direi che questa è di gran lunga la risposta migliore.
ACK_stoverflow

Sì, ad oggi, solo browser molto vecchi (IE> 10, Safari> 7, FF veramente antichi, Chrome) e / o oscuri (Opera Mini) non supportano l' outerHTMLattributo. Vedi anche caniuse.com/#feat=xml-serializer
Gert Sønderby

20

Non penso che tu abbia bisogno di uno script complicato per questo. Basta usare

get_string=(el)=>el.outerHTML;

questa è la risposta migliore
Avraham

15

Sotto FF puoi usare l' XMLSerializeroggetto per serializzare XML in una stringa. IE ti dà una xmlproprietà di un nodo. Quindi puoi fare quanto segue:

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

FYI .xmlnon funziona sui nodi DOM (come nei nodi nella pagina corrente). Funziona solo sui nodi del documento XML DOM.
Crescent Fresh

E viceversa, outerHTMLnon funziona sui nodi del documento XML DOM. Funziona solo sui nodi DOM (come nei nodi nella pagina corrente). Buona consistenza lì direi.
Crescent Fresh

7

Usa Element # outerHTML:

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

console.log(el.outerHTML);

Può anche essere usato per scrivere elementi DOM. Dalla documentazione di Mozilla:

L'attributo outerHTML dell'interfaccia DOM dell'elemento ottiene il frammento HTML serializzato che descrive l'elemento, inclusi i suoi discendenti. Può essere impostato per sostituire l'elemento con nodi analizzati dalla stringa data.

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


3

Usa element.outerHTML per ottenere la rappresentazione completa dell'elemento, inclusi i tag esterni e gli attributi.


1

Se il tuo elemento ha parent

element.parentElement.innerHTML

2
Grazie per la risposta! Sfortunatamente era già stato suggerito, ma chi ha risposto ha cancellato la risposta. Il problema è che il genitore potrebbe contenere molto più markup di quanto desiderato. Pensa a outerHTML per un singolo <li>in un elenco.
Boldewyn

1

Provare

new XMLSerializer().serializeToString(element);

Grazie per il suggerimento, ma è esattamente quello che ha suggerito Bryan Kale nella sua risposta.
Boldewyn

1

Ho scoperto che per i miei casi d'uso non voglio sempre l'intero outerHTML. Molti nodi hanno semplicemente troppi figli da mostrare.

Ecco una funzione (minimamente testata in 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

Ho perso un sacco di tempo a capire cosa c'è che non va quando itero attraverso DOMElements con il codice nella risposta accettata. Questo è quello che ha funzionato per me, altrimenti ogni secondo elemento scompare dal documento:

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

1
Non esco su un arto, quando suppongo che tu abbia un problema diverso qui. Si noti che la soluzione precedente rimuove l'elemento originale dal DOM. Quindi, quando usi una raccolta dal vivo come document.getElementsByTagName(), quella collezione cambierà a metà forciclo, da qui il salto di ogni secondo elemento.
Boldewyn

-1

se si utilizza reagire:

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

.outerHTMLnon è specifico di React; è uno standard DOM. Dai un'occhiata alla risposta di @Rich Apodaca.
chharvey

sì ... il punto di interesse (se si utilizza reagire) sulla mia risposta era reactdom.findDOMNode()..., non il .outerHTML, ma grazie per la posizione.
victorkurauchi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.