Chèn các phần tử HTML bằng JavaScript


105

Thay vì tốn công tìm kiếm các giải pháp thay thế cho từng loại thuộc tính và sự kiện khi sử dụng cú pháp sau:

elem = document.createElement("div");
elem.id = 'myID';
elem.innerHTML = ' my Text '
document.body.insertBefore(elem,document.body.childNodes[0]);

Có cách nào để tôi có thể khai báo toàn bộ phần tử HTML dưới dạng một chuỗi không? giống:

elem = document.createElement("<div id='myID'> my Text </div>");
document.body.insertBefore(elem,document.body.childNodes[0]);

Câu trả lời:


124

Thay vì trực tiếp làm rối innerHTMLnó có thể tốt hơn là tạo một phân đoạn và sau đó chèn:

function create(htmlStr) {
    var frag = document.createDocumentFragment(),
        temp = document.createElement('div');
    temp.innerHTML = htmlStr;
    while (temp.firstChild) {
        frag.appendChild(temp.firstChild);
    }
    return frag;
}

var fragment = create('<div>Hello!</div><p>...</p>');
// You can use native DOM methods to insert the fragment:
document.body.insertBefore(fragment, document.body.childNodes[0]);

Những lợi ích:

  1. Bạn có thể sử dụng các phương thức DOM gốc để chèn như insertBefore, appendChild, v.v.
  2. Bạn có quyền truy cập vào các nút DOM thực tế trước khi chúng được chèn vào; bạn có thể truy cập đối tượng childNodes của mảnh.
  3. Sử dụng các đoạn tài liệu rất nhanh chóng; nhanh hơn việc tạo các phần tử bên ngoài DOM và trong một số trường hợp nhất định nhanh hơn innerHTML.

Mặc dù innerHTMLđược sử dụng trong hàm, tất cả đều diễn ra bên ngoài DOM nên nó nhanh hơn nhiều so với bạn nghĩ ...


3
Tôi cá rằng createDocumentFragment () này sẽ không tốt bằng innerHTML "kế thừa".
TheFlash

2
Phương pháp này hoạt động trên tất cả các trình duyệt hiện đại. Đối với IE 5.5 trở xuống, bạn có thể thực hiện kiểm tra như :: if (document.createDocumentFragment) {create ('...'); } else {/ * Sử dụng innerHTML có lẽ * /}
James

32
crescentfresh, tôi giúp đỡ trên SO vì tôi thích giúp đỡ mọi người; Tôi rất tiếc nếu một giải pháp không thể hoạt động 100% trong mọi tình huống. Nếu bạn quá lo lắng, tại sao không đưa ra giải pháp của riêng bạn thay vì chỉ trích một cách không cần thiết những câu trả lời đã được đưa ra? Với bất kỳ sự trừu tượng nào sẽ luôn có các trường hợp cạnh! Đây là một môi trường học tập - chúng tôi không ở đây để cung cấp cho mọi người một giải pháp - chúng tôi ở đây để giúp nhau trở nên tốt hơn trong những gì chúng tôi làm! Và xin lỗi, nhưng đã có ai đề cập đến "AJAX" ở đâu?
James

1
Đủ công bằng. Lời xin lỗi của tôi. Tôi chỉ cảm thấy rằng có rất nhiều điều trừu tượng ở đây mà không có cảnh báo nào được đề cập.
Crescent Fresh

1
cách này phức tạp hơn mức cần thiết - câu trả lời của sime vidas tốt hơn nhiều
JonnyRaa

83

Bạn muốn điều này

document.body.insertAdjacentHTML( 'afterbegin', '<div id="myID">...</div>' );

13
không chắc tại sao đây không phải là câu trả lời được chấp nhận. Cách này đơn giản hơn và rõ ràng là chính xác
JonnyRaa

@JonnyLeeds điều này dường như không hoạt động trên bodyphần tử nhưng hoạt động tốt trên bất kỳ phần tử nào khác.
Phill

1
@Phill Tất nhiên là nó hoạt động <body>. Trên thực tế, chạy nó <body>là phương pháp tiêu chuẩn của tôi để đưa những thứ như style sheet vào các trang web thông qua bảng điều khiển. Bạn đang gặp vấn đề gì
Šime Vidas

@ ŠimeVidas có lẽ vì các yếu tố cơ thể đã không được quy định tại thời gian thực hiện ... i cặp dòng của bạn với window.onload = function () {...} để ngăn chặn điều đó vấn đề
GDY

@Grandy Phill đã viết rằng nó hoạt động trên các yếu tố khác. Nếu <body>không được xác định, tất cả các yếu tố khác cũng vậy, vì vậy đây có thể không phải là vấn đề của Phill.
Šime Vidas

32

Hãy xem insertAdjacentHTML

var element = document.getElementById("one");
var newElement = '<div id="two">two</div>'
element.insertAdjacentHTML( 'afterend', newElement )
// new DOM structure: <div id="one">one</div><div id="two">two</div>

vị trí là vị trí liên quan đến phần tử bạn đang chèn bên cạnh:

'beforebegin' Trước chính phần tử

'afterbegin' Ngay bên trong phần tử, trước phần tử con đầu tiên của nó

'beforeend' Ngay bên trong phần tử, sau phần tử cuối cùng của nó

'afterend' Sau chính phần tử


17

Trong JavaScript trường cũ, bạn có thể làm điều này:

document.body.innerHTML = '<p id="foo">Some HTML</p>' + document.body.innerHTML;

Để trả lời bình luận của bạn:

[...] Tôi quan tâm đến việc khai báo nguồn của các thuộc tính và sự kiện của phần tử mới, không phải innerHTMLcủa một phần tử.

Tuy nhiên, bạn cần đưa HTML mới vào DOM; đó là lý do tại sao innerHTMLđược sử dụng trong ví dụ JavaScript trường học cũ. Các innerHTMLcủaBODY phần tử được thêm vào phía trước với HTML mới. Chúng tôi không thực sự chạm vào HTML hiện có bên trongBODY .

Tôi sẽ viết lại ví dụ nói trên để làm rõ điều này:

var newElement = '<p id="foo">This is some dynamically added HTML. Yay!</p>';
var bodyElement = document.body;
bodyElement.innerHTML = newElement + bodyElement.innerHTML;
// note that += cannot be used here; this would result in 'NaN'

Sử dụng khung JavaScript sẽ làm cho mã này ít dài dòng hơn nhiều và cải thiện khả năng đọc. Ví dụ: jQuery cho phép bạn thực hiện những việc sau:

$('body').prepend('<p id="foo">Some HTML</p>');

Khá tốt. Nhưng tôi quan tâm đến việc khai báo nguồn của các thuộc tính và sự kiện của một phần tử mới, không phải là InternalHTML của một phần tử.
TheFlash

1
document.getElementsByTagName('body')[0]thực sự có thể được thay thế bằng document.body, điểm tốt. Tuy nhiên, nếu bạn muốn thêm trước hoặc nối thêm HTML mới vào một phần tử hiện có khác thay vì BODY, bạn sẽ phải sử dụng document.getElementById()và / hoặc document.getElementsByTagName(); đó là lý do tại sao tôi sử dụng nó trong ví dụ.
Mathias Bynens

1
Ngoài ra, mã của bạn có thể rất lộn xộn rất nhanh nếu bạn đang trực tiếp thêm / chèn "innerHTML"
James

1
@JimmyP: Đồ rác rưởi! Mục đích của câu hỏi này là có thể chèn trực tiếp HTML dưới dạng chuỗi thay vì chơi xung quanh với các hàm để xây dựng nó, phân bổ theo quy tắc, nút theo nút, phần tử theo phần tử.
TheFlash

1
điều này tách tất cả các trình xử lý sự kiện và có thể gây rò rỉ bộ nhớ trong thời gian dài.
adardesign

1

Theo hiểu biết của tôi, công bằng mà nói, nó khá mới và hạn chế, vấn đề tiềm ẩn duy nhất với kỹ thuật này là thực tế là bạn bị ngăn cản việc tạo động một số phần tử bảng.

Tôi sử dụng một biểu mẫu để tạo mẫu bằng cách thêm các phần tử "mẫu" vào một DIV ẩn và sau đó sử dụng cloneNode (true) để tạo một bản sao và gắn nó theo yêu cầu. Lưu ý rằng bạn cần đảm bảo bạn chỉ định lại id theo yêu cầu để tránh trùng lặp.


-1

Như những người khác nói rằng thuận tiện jQuery thêm vào trước chức năng có thể được mô phỏng:

var html = '<div>Hello prepended</div>';
document.body.innerHTML = html + document.body.innerHTML;

Trong khi một số người nói rằng tốt hơn là không nên "gây rối" với innerHTML , nó đáng tin cậy trong nhiều trường hợp sử dụng, nếu bạn biết điều này:

Nếu a <div>, <span>hoặc <noembed>nút có một nút văn bản con bao gồm các ký tự (& ), ( <) hoặc ( >), thì innerHTML trả về các ký tự này dưới dạng &amp, &lt&gttương ứng. Sử dụng Node.textContentđể có được một bản sao chính xác nội dung của các nút văn bản này.

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

Hoặc là:

var html = '<div>Hello prepended</div>';
document.body.insertAdjacentHTML('afterbegin', html)

insertAdjacentHTMLcó lẽ là một giải pháp thay thế tốt: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML


-2

Nếu bạn muốn chèn mã HTML bên trong thẻ của trang hiện có, hãy sử dụng Jnerator . Công cụ này được tạo ra đặc biệt cho mục tiêu này.

Thay vì viết mã tiếp theo

    var htmlCode = '<ul class=\'menu-countries\'><li
        class=\'item\'><img src=\'au.png\'></img><span>Australia </span></li><li
        class=\'item\'><img src=\'br.png\'> </img><span>Brazil</span></li><li
        class=\'item\'> <img src=\'ca.png\'></img><span>Canada</span></li></ul>';
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;

Bạn có thể viết cấu trúc dễ hiểu hơn

    var jtag = $j.ul({
        class: 'menu-countries',
        child: [
            $j.li({ class: 'item', child: [
                $j.img({ src: 'au.png' }),
                $j.span({ child: 'Australia' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'br.png' }),
                $j.span({ child: 'Brazil' })
            ]}),
            $j.li({ class: 'item', child: [
                $j.img({ src: 'ca.png' }),
                $j.span({ child: 'Canada' })
            ]})
        ]
    });
    var htmlCode = jtag.html();
    var element = document.getElementById('myTag');
    element.innerHTML = htmlCode;
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.