Nối chuỗi HTML vào DOM


121

Cách nối chuỗi HTML này

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

đến DIV với ID 'test'có trong DOM?

(Btw div.innerHTML += str;không được chấp nhận.)

Câu trả lời:


241

Sử dụng insertAdjacentHTMLnếu nó có sẵn, nếu không sử dụng một số loại dự phòng. insertAdjighborHTML được hỗ trợ trong tất cả các trình duyệt hiện tại .

div.insertAdjacentHTML( 'beforeend', str );

Bản demo trực tiếp: http://jsfiddle.net/euQ5n/


1
@alex Đó là khái niệm tương tự: phân tích chuỗi HTML và đưa nó vào DOM. Nhưng chức năng thì khác - innerHTMLđặt chuỗi vào phần tử (thay thế tất cả các phần tử con), trong khi insertAdjacentHTMLđặt nó (1) trước phần tử, (2) sau phần tử, (3) bên trong phần tử trước phần tử con đầu tiên hoặc (4) bên trong các yếu tố sau khi đứa trẻ cuối cùng.
Vidime Vidas

3
@alex insertAdjacentHTMLnhanh hơn so với việc thêm vào innerHTML, bởi vì insertAdjacentHTMLkhông tuần tự hóa và lặp lại các phần tử con hiện có của phần tử.
hsivonen

2
Ngoài ra, insertAdjacentHTMLduy trì các giá trị của các phần tử biểu mẫu đã thay đổi, trong khi bổ sung để innerHTMLxây dựng lại phần tử và mất tất cả bối cảnh biểu mẫu.
Brandon Gano

20

điều này có chấp nhận được không?

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

jsFiddle .

Nhưng , câu trả lời của Neil là một giải pháp tốt hơn.


1
@ Šime Làm việc với API DOM luôn có cảm giác như bị hack: P Bạn có muốn hủy xác nhận chuỗi mà không có innerHTML ?
alex

Vâng, nếu có một cách khác để sử dụng trình phân tích cú pháp HTML của trình duyệt, tôi rất muốn biết ...
Vidime Vidas

1
@ Šime - Tôi nghĩ chỉ có hai cách để sử dụng trình phân tích cú pháp HTML của trình duyệt, InternalHTML và document.write. Và nếu bạn nghĩ InternalHTML là một hack ...
Alohci

@Alohci Có một cách khác: insertAdjacentHTML.
Vidime Vidas

1
@ Ime -Cảm ơn. Tôi tìm thấy phiên bản WHATWG. Nó nằm trong thông số DOM Parsing và serialization . Nó chỉ ra rằng cũng như InternalHTML và insertAdjiềnHTML, bên ngoàiHTML và, tôi nghĩ, createdContextualFragment.
Alohci

16

Hiệu suất

AppendChild(E) nhanh hơn gấp 2 lần so với các giải pháp khác trên chrome và safari, insertAdjacentHTML(F) nhanh nhất trên firefox. Các innerHTML=(B) (Đừng nhầm lẫn với +=(A)) là giải pháp nhanh thứ hai trên tất cả các trình duyệt và nó là nhiều hơn nữa tiện dụng hơn so với E và F.

Chi tiết

Thiết lập môi trường (2019.07.10) MacOs High Sierra 10.13.4 trên Chrome 75.0.3770 (64-bit), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-bit)

nhập mô tả hình ảnh ở đây

  • trên Chrome E (hoạt động 140k mỗi giây) là nhanh nhất, B (47k) và F (46k) là thứ hai, A (332) là chậm nhất
  • trên firefox F (94k) là nhanh nhất, sau đó B (80k), D (73k), E (64k), C (21k) chậm nhất là A (466)
  • trên Safari E (207k) là nhanh nhất, sau đó B (89k), F (88k), D (83k), C (25k), chậm nhất là A (509)

Bạn có thể phát lại bài kiểm tra trong máy của bạn ở đây


12

Ý tưởng là sử dụng innerHTMLtrên một phần tử trung gian và sau đó di chuyển tất cả các nút con của nó đến nơi bạn thực sự muốn chúng đi qua 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);
}

Điều này tránh xóa sạch mọi trình xử lý sự kiện trên div#testnhưng vẫn cho phép bạn nối thêm một chuỗi HTML.


3

Cách đúng là sử dụng insertAdjacentHTML. Trong Firefox sớm hơn 8, bạn có thể quay lại sử dụng Range.createContextualFragmentnếu strkhông chứa scriptthẻ.

Nếu thẻ strchứa của bạn script, bạn cần xóa scriptcác phần tử khỏi đoạn được trả về createContextualFragmenttrước khi chèn đoạn. Nếu không, các kịch bản sẽ chạy. ( insertAdjacentHTMLđánh dấu các tập lệnh không thể thực hiện được.)


Cảm ơn bạn đã đề cập createContextualFragment . Tôi đã tìm kiếm một cách để làm cho một số html bao gồm các tập lệnh chỉ chạy nếu người dùng đồng ý đặt cookie.
schliflo

3

Hack nhanh :


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

Các trường hợp sử dụng :

1: Lưu dưới dạng tệp .html và chạy trong chrome hoặc firefox hoặc edge. (IE không hoạt động)

2: Sử dụng trong http://js.do

Đang hoạt động: http://js.do/HeavyMetalCookies/quick_hack

Chia nhỏ với ý kiến:

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

Lý do tại sao tôi đăng:

JS.do có hai phải có:

  1. Không tự động hoàn thành
  2. Màn hình dọc thân thiện

Nhưng không hiển thị tin nhắn console.log. Đến đây để tìm kiếm một giải pháp nhanh chóng. Tôi chỉ muốn xem kết quả của một vài dòng mã Scratchpad, các giải pháp khác là quá nhiều công việc.


1

Tại sao điều đó không được chấp nhận?

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

sẽ là cách làm sách giáo khoa.


4
Nó sẽ giết người xử lý sự kiện kèm theo #testmặc dù. Điều đó nói chung là không mong muốn.
alex

Thật thú vị khi nó làm điều đó. Có vẻ không hợp lý thực sự.
Nick Brunt

2
Tôi đoán là hợp lý nếu bạn nghĩ về việc tuần tự hóa HTML thành một chuỗi và sau đó đặt lại HTML.
alex

Tôi đoán JavaScript sẽ phải được chạy lại để thiết lập trình xử lý sự kiện. Đủ công bằng.
Nick Brunt

1
@Nick Bạn không muốn xâu chuỗi (tuần tự hóa) một phần của DOM chỉ để bạn có thể nối chuỗi đó với một chuỗi khác và sau đó phân tích lại toàn bộ điều đó vào DOM. Như alex đã nói, việc xê-ri hóa sẽ không ghi lại các trình xử lý sự kiện bị ràng buộc (trong số những thứ khác). Ngay cả khi anh ta tuần tự hóa có thể nắm bắt mọi thứ, bạn vẫn sẽ không muốn làm điều đó.
Vidime Vidas

0

Điều này có thể giải quyết

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');

3
Chào mừng bạn đến với Stack tràn. Vui lòng giải thích mã của bạn như một phần của câu trả lời để cung cấp một số ngữ cảnh thay vì chỉ dán một dòng mã dài. Mặc dù bạn hiểu nó nhưng những người khác có thể không hiểu những gì nó đang làm.
loan.burger

0

InternalHTML xóa tất cả dữ liệu như sự kiện cho các nút hiện có

chắp thêm con với FirstChild chỉ thêm con đầu tiên vào bên trongHTML. Ví dụ: nếu chúng ta phải nối thêm:

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

chỉ text1 sẽ hiển thị

Cái này thì sao:

thêm thẻ đặc biệt vào InternalHTML bằng cách nối thêm con và sau đó chỉnh sửa bên ngoàiHTML bằng cách xóa thẻ chúng tôi đã tạo. Không biết nó thông minh như thế nào nhưng nó hoạt động với tôi hoặc bạn có thể thay đổi bên ngoàiHTML sang bên trongHTML để không phải sử dụng chức năng thay thế

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>


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.