Dapatkan representasi string dari simpul DOM

96

Javascript: Saya memiliki representasi DOM dari sebuah node (elemen atau dokumen) dan saya mencari representasi stringnya. Misalnya,

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

harus menghasilkan:

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

Saya memiliki perasaan yang kuat, bahwa saya melewatkan sesuatu yang sepele yang sederhana, tetapi saya tidak menemukan metode yang berfungsi di IE, FF, Safari dan Opera. Oleh karena itu, HTML luar bukanlah pilihan.

Boldewyn
sumber
4
Dengan kemungkinan versi 11 Firefox juga mendukung outerHTML: bugzilla.mozilla.org/show_bug.cgi?id=92264
Boldewyn
1
Untuk saat ini, lihat IE, FF, Safari, Chrome, Opera semua mendukung outerHTML, lihat developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
wangf
1
Ya, sekarang (sejak 2009, itulah) menjadi tugas yang sepele :)
Boldewyn
Ya, pasti luarHTML
neaumusic

Jawaban:

133

Anda dapat membuat node induk sementara, dan mendapatkan konten innerHTML-nya:

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: Silakan lihat jawaban di bawah tentang outerHTML. el.outerHTML harus menjadi semua yang dibutuhkan.

CMS
sumber
1
Aduh. Sangat sederhana ... Sedikit catatan: Jika saya ingin seluruh dokumen "dirangkai", saya dapat menggunakan metode yang sama dengan document.documentElement (usecase: permintaan AJAX). Mungkin Anda bisa memasukkannya ke dalam jawaban?
Boldewyn
3
@Boldewyn: Anda dapat menambahkan keseluruhan document.documentElementke dalam div?
Sialan
Sederhana, sekali ... +1 documentFragment yang terlalu buruk tidak mendukung innerHTML
Lajos Meszaros
30
outerHTML adalah jawabannya
neaumusic
3
Jangan lupa untuk mengkloning Anda elementsebelum menambahkannya ke tmpkarena saat Anda menambahkannya tmp, itu akan dihapus dari document.
Olcay Ertaş
44

Apa yang Anda cari adalah 'outerHTML', tapi kami membutuhkan penggantian karena tidak kompatibel dengan browser lama.

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

Anda akan menemukan plugin jQuery saya di sini: Dapatkan HTML luar elemen yang dipilih

gtournie
sumber
Firefox ditambahkan outerHTMLdi versi 11, setelah saya mengajukan pertanyaan. Jadi itu bukan pilihan saat itu. Saya bahkan memperbarui pertanyaan saya dengan komentar yang sesuai, jika Anda melihat lebih dekat.
Boldewyn
Ini benar, karena Anda menjatuhkan id elemen dan atribut lainnya jika digunakaninnerHtml
Sergei Panfilov
1
@SergeyPanfilov: Saya tidak menjatuhkan apapun karena saya membungkus node dalam div kosong sebelum memanggil innerHTML; )
gtournie
3
Pada tahun 2015, saya akan mengatakan ini adalah jawaban terbaik sejauh ini.
ACK_stoverflow
Ya, untuk hari ini, hanya yang sangat lama (IE> 10, Safari> 7, FF yang benar-benar kuno, Chrome) dan / atau browser tidak dikenal (Opera Mini) yang tidak mendukung outerHTMLatribut tersebut. Lihat juga caniuse.com/#feat=xml-serializer
Gert Sønderby
20

Saya tidak berpikir Anda memerlukan skrip rumit untuk ini. Gunakan saja

get_string=(el)=>el.outerHTML;
Shishir Arora
sumber
ini adalah jawaban terbaik
Avraham
15

Di bawah FF Anda dapat menggunakan XMLSerializerobjek untuk membuat serial XML menjadi string. IE memberi Anda xmlproperti dari sebuah node. Jadi, Anda dapat melakukan hal berikut:

function xml2string(node) {
   if (typeof(XMLSerializer) !== 'undefined') {
      var serializer = new XMLSerializer();
      return serializer.serializeToString(node);
   } else if (node.xml) {
      return node.xml;
   }
}
Bryan Kyle
sumber
FYI .xmltidak bekerja pada node DOM (seperti node di halaman saat ini). Ini hanya bekerja pada node dokumen XML DOM.
Crescent Fresh
Dan sebaliknya, outerHTMLtidak berfungsi pada node dokumen XML DOM. Ini hanya berfungsi pada simpul DOM (seperti pada simpul di halaman saat ini). Konsistensi yang baik menurut saya.
Crescent Fresh
7

Gunakan Elemen # outerHTML:

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

console.log(el.outerHTML);

Ini juga dapat digunakan untuk menulis elemen DOM. Dari dokumentasi Mozilla:

Atribut outerHTML dari elemen antarmuka DOM mendapatkan fragmen HTML serial yang mendeskripsikan elemen termasuk turunannya. Ini dapat diatur untuk mengganti elemen dengan node yang diurai dari string yang diberikan.

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

Apodaca Kaya
sumber
3

Gunakan element.outerHTML untuk mendapatkan representasi penuh dari elemen, termasuk tag dan atribut luar.

Pavel V.
sumber
1

Jika elemen Anda memiliki induk

element.parentElement.innerHTML
Vincnetas
sumber
2
Terima kasih atas jawabannya! Sayangnya itu sudah disarankan, tetapi penjawab menghapus jawabannya. Masalahnya adalah, induk mungkin berisi markup lebih banyak daripada yang diinginkan. Pikirkan outerHTML untuk satu <li>dalam daftar.
Boldewyn
1

Mencoba

new XMLSerializer().serializeToString(element);
Alex Popa
sumber
Terima kasih atas sarannya, tetapi itulah yang disarankan Bryan Kale dalam jawabannya.
Boldewyn
1

Saya telah menemukan bahwa untuk kasus penggunaan saya, saya tidak selalu menginginkan keseluruhan HTML luar. Banyak node yang memiliki terlalu banyak turunan untuk ditampilkan.

Berikut fungsinya (diuji minimal di 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

Aaron
sumber
0

Saya telah membuang banyak waktu untuk mencari tahu apa yang salah ketika saya beralih melalui DOMElements dengan kode di jawaban yang diterima. Inilah yang berhasil untuk saya, jika tidak, setiap elemen detik menghilang dari dokumen:

_getGpxString: function(node) {
          clone = node.cloneNode(true);
          var tmp = document.createElement("div");
          tmp.appendChild(clone);
          return tmp.innerHTML;
        },
balagan
sumber
1
Saya tidak mengambil risiko, ketika saya kira, Anda memiliki masalah yang berbeda di sini. Perhatikan, bahwa solusi di atas menghapus elemen asli dari DOM. Jadi, saat Anda menggunakan koleksi langsung seperti document.getElementsByTagName(), koleksi itu akan berubah di tengah-tengah for, sehingga elemen detik terlewati.
Boldewyn
-1

jika menggunakan react:

const html = ReactDOM.findDOMNode(document.getElementsByTagName('html')[0]).outerHTML;
victorkurauchi
sumber
.outerHTMLtidak spesifik React; itu adalah standar DOM. Lihat jawaban @Rich Apodaca.
chharvey
ya ... poin yang menarik (jika menggunakan react) pada jawaban saya adalah reactdom.findDOMNode()..., bukan .outerHTML, tapi terima kasih atas posisinya.
victorkurauchi