Menambahkan string HTML ke DOM

121

Cara menambahkan string HTML ini

var str = '<p>Just some <span>text</span> here</p>';

ke DIV dengan ID 'test'yang ada di DOM?

(Btw div.innerHTML += str;tidak dapat diterima.)

Šime Vidas
sumber

Jawaban:

243

Gunakan insertAdjacentHTMLjika tersedia, jika tidak, gunakan semacam fallback. insertTentangHTML didukung di semua browser saat ini .

div.insertAdjacentHTML( 'beforeend', str );

Demo langsung: http://jsfiddle.net/euQ5n/

Neil
sumber
1
@alex Konsepnya sama: mengurai string HTML dan memasukkannya ke DOM. Tetapi fungsinya berbeda - innerHTMLmenempatkan string ke dalam elemen (menggantikan semua anak), sedangkan insertAdjacentHTMLmenempatkannya (1) sebelum elemen, (2) setelah elemen, (3) di dalam elemen sebelum anak pertama, atau (4) di dalam elemen setelah anak terakhir.
Šime Vidas
3
@alex insertAdjacentHTMLlebih cepat daripada menambahkan ke innerHTML, karena insertAdjacentHTMLtidak membuat serial dan reparse turunan elemen yang sudah ada.
hsivonen
2
Juga, insertAdjacentHTMLmempertahankan nilai elemen formulir yang diubah, sedangkan menambahkan untuk innerHTMLmembangun kembali elemen dan kehilangan semua konteks formulir.
Brandon Gano
20

Apakah ini dapat diterima?

var child = document.createElement('div');
child.innerHTML = str;
child = child.firstChild;
document.getElementById('test').appendChild(child);

jsFiddle .

Tapi , jawaban Neil adalah solusi yang lebih baik.

alex
sumber
1
@ Šime Bekerja dengan API DOM selalu terasa seperti retasan : P Apakah Anda lebih suka melepaskan string tanpa serial innerHTML?
alex
Ya, jika ada cara lain untuk menggunakan pengurai HTML browser, saya ingin tahu ...
Šime Vidas
1
@ Šime - Saya pikir hanya ada dua cara untuk menggunakan parser HTML browser, innerHTML dan document.write. Dan jika menurut Anda innerHTML adalah
retasan
@Alohci Ada adalah cara lain: insertAdjacentHTML.
Šime Vidas
1
@ Šime -Terima kasih. Saya menemukan versi WHATWG. Ini ada dalam spesifikasi Parsing dan Serialisasi DOM . Ini menunjukkan bahwa selain innerHTML dan insertAdectingHTML, ada outerHTML dan, menurut saya, createContextualFragment.
Alohci
16

Performa

AppendChild(E) lebih dari 2x lebih cepat daripada solusi lain di chrome dan safari, insertAdjacentHTML(F) tercepat di firefox. The innerHTML=(B) (tidak bingung dengan +=(A)) adalah solusi cepat kedua pada semua browser dan itu jauh lebih berguna daripada E dan F.

Detail

Lingkungan pengaturan (2019.07.10) MacOs High Sierra 10.13.4 di Chrome 75.0.3770 (64-bit), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-bit)

masukkan deskripsi gambar di sini

  • di Chrome E (140k operasi per detik) tercepat, B (47k) dan F (46k) detik, A (332) paling lambat
  • pada firefox F (94k) tercepat, lalu B (80k), D (73k), E (64k), C (21k) paling lambat adalah A (466)
  • di Safari E (207k) adalah yang tercepat, lalu B (89k), F (88k), D (83k), C (25k), paling lambat adalah A (509)

Anda dapat memutar ulang pengujian di mesin Anda di sini

Kamil Kiełczewski
sumber
12

Idenya adalah menggunakan innerHTMLelemen perantara dan kemudian memindahkan semua node turunannya ke tempat yang Anda inginkan appendChild.

var target = document.getElementById('test');
var str = '<p>Just some <span>text</span> here</p>';

var temp = document.createElement('div');
temp.innerHTML = str;
while (temp.firstChild) {
  target.appendChild(temp.firstChild);
}

Ini untuk menghindari penghapusan semua penangan acara, div#testtetapi masih memungkinkan Anda untuk menambahkan string HTML.

Chris Calo
sumber
3

Cara yang benar adalah menggunakan insertAdjacentHTML. Di Firefox sebelum 8, Anda dapat kembali menggunakan Range.createContextualFragmentjika Anda strtidak berisi scripttag.

Jika Anda strmengandung scripttag, Anda perlu menghapus scriptelemen dari fragmen yang dikembalikan oleh createContextualFragmentsebelum memasukkan fragmen. Jika tidak, skrip akan berjalan. ( insertAdjacentHTMLmenandai skrip tidak dapat dieksekusi.)

hsivonen.dll
sumber
Terima kasih telah menyebutkan createContextualFragment . Saya sedang mencari cara untuk membuat beberapa html yang disertakan dengan skrip yang dijalankan hanya jika pengguna setuju untuk mengatur cookie.
schliflo
3

Retas Cepat :


<script>
document.children[0].innerHTML="<h1>QUICK_HACK</h1>";
</script>

Kasus Penggunaan :

1: Simpan sebagai file .html dan jalankan di chrome atau firefox atau edge. (IE tidak akan berfungsi)

2: Gunakan di http://js.do

Beraksi: http://js.do/HeavyMetalCookies/quick_hack

Dipecah dengan komentar:

<script>

//: The message "QUICK_HACK" 
//: wrapped in a header #1 tag.
var text = "<h1>QUICK_HACK</h1>";

//: It's a quick hack, so I don't
//: care where it goes on the document,
//: just as long as I can see it.
//: Since I am doing this quick hack in
//: an empty file or scratchpad, 
//: it should be visible.
var child = document.children[0];

//: Set the html content of your child
//: to the message you want to see on screen.
child.innerHTML = text;

</script>

Alasan saya memposting:

JS.do memiliki dua hal yang harus dimiliki:

  1. Tidak ada pelengkapan otomatis
  2. Ramah monitor vertikal

Tapi tidak menampilkan pesan console.log. Datang ke sini mencari solusi cepat. Saya hanya ingin melihat hasil dari beberapa baris kode papan gores, solusi lainnya terlalu banyak bekerja.

JMI MADISON
sumber
1

Mengapa itu tidak bisa diterima?

document.getElementById('test').innerHTML += str

akan menjadi cara buku teks melakukannya.

Nick Brunt
sumber
4
Itu akan membunuh penangan acara yang melekat padanya #test. Itu umumnya tidak diinginkan.
alex
Menarik bahwa itu melakukan itu. Sepertinya tidak logis.
Nick Brunt
2
Ini logis saya kira jika Anda berpikir tentang menserialisasi HTML ke string dan kemudian mengatur HTML kembali.
alex
Saya kira JavaScript harus dijalankan lagi untuk mengatur ulang event handler. Cukup adil.
Nick Brunt
1
@Nick Anda tidak ingin merangkai (membuat serial) bagian dari DOM hanya agar Anda dapat menggabungkannya dengan string lain dan kemudian mengurai semuanya kembali ke DOM. Seperti yang dikatakan alex, serialisasi tidak akan merekam penangan event terikat (antara lain). Bahkan jika serialisasi dia dapat menangkap semuanya, Anda tetap tidak ingin melakukannya.
Šime Vidas
0

Ini bisa memecahkan

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');
Rafael Senne
sumber
3
Selamat datang di Stack overflow. Harap jelaskan kode Anda sebagai bagian dari jawaban untuk memberikan beberapa konteks daripada hanya menempelkan satu baris kode yang panjang. Meskipun Anda memahaminya, orang lain mungkin tidak mengerti apa yang dilakukannya.
loan.burger
0

InnerHTML menghapus semua data seperti acara untuk node yang ada

menambahkan anak dengan firstChild hanya menambahkan anak pertama ke innerHTML. Misalnya jika kita harus menambahkan:

 <p>text1</p><p>text2</p>

hanya teks1 yang akan muncul

Bagaimana dengan ini:

menambahkan tag khusus ke innerHTML dengan menambahkan anak lalu mengedit HTML luar dengan menghapus tag yang telah kita buat. Tidak tahu seberapa pintar itu tetapi berfungsi untuk saya atau Anda mungkin mengubah HTML luar ke dalamHTML sehingga tidak harus menggunakan fungsi pengganti

function append(element, str)
{

  var child = document.createElement('someshittyuniquetag');
		
  child.innerHTML = str;

  element.appendChild(child);

  child.outerHTML = child.outerHTML.replace(/<\/?someshittyuniquetag>/, '');

// or Even child.outerHTML = child.innerHTML


  
}
<div id="testit">
This text is inside the div
<button onclick="append(document.getElementById('testit'), '<button>dadasasdas</button>')">To div</button>
<button onclick="append(this, 'some text')">to this</button>
</div>

Łukasz Szpak
sumber
0

Terpendek - 18 karakter (tidak membingungkan +=(disebutkan oleh OP) dengan =detail lebih lanjut di sini )

test.innerHTML=str

Kamil Kiełczewski
sumber