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.


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.


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


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;

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;
   }
}

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


3

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


1

Jika elemen Anda memiliki induk

element.parentElement.innerHTML

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);

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


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;
        },

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;

.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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.