JQuery html () so với innerHTML


80

Tôi có thể hoàn toàn dựa vào html()phương thức của jQuery hoạt động giống như innerHTMLkhông? Có sự khác biệt nào giữa innerHTMLhtml()phương thức của jQuery không? Nếu cả hai phương thức này đều hoạt động giống nhau, tôi có thể sử dụng html()phương thức của jQuery thay cho innerHTMLkhông?

Vấn đề của tôi là: Tôi đang làm việc trên các trang đã được thiết kế sẵn, các trang chứa bảng và trong JavaScript thuộc innerHTMLtính đang được sử dụng để điền chúng động.

Ứng dụng này đang làm việc tốt trên Firefox nhưng Internet Explorer cháy một lỗi: unknown runtime exception. Tôi đã sử dụng html()phương pháp của jQuery và lỗi của IE đã biến mất. Nhưng tôi không chắc nó sẽ hoạt động với tất cả các trình duyệt và tôi không chắc liệu có nên thay thế tất cả các innerHTMLthuộc tính bằng html()phương thức của jQuery hay không .

Cảm ơn rất nhiều.


9
sử dụng jQuery html (). Tôi đã gặp sự cố với innerHTML trong nhiều trường hợp. Và html () sẽ hoạt động trên tất cả các trình duyệt.
Glavić

Câu trả lời:


117

Để trả lời câu hỏi của bạn:

.html()sẽ chỉ gọi .innerHTMLsau khi thực hiện một số kiểm tra nodeTypes và nội dung. Nó cũng sử dụng một try/catchkhối mà nó cố gắng sử dụng innerHTMLtrước và nếu không thành công, nó sẽ dự phòng một cách duyên dáng vào .empty()+ của jQueryappend()


13
Lưu ý rằng với Internet Explorer 8 (và có thể là sớm hơn), các lần kiểm tra bổ sung có thể tăng hiệu suất đáng kể cho các chèn lớn, vì vậy nếu hiệu suất trên IE là quan trọng, bạn có thể muốn xem xét sử dụng innerHTMLtrực tiếp.
sroebuck

3
So sánh hiệu suất ngắn gọn: jsperf.com/innerhtml-vs-html-vs-empty-append
thdoan

17

Cụ thể là về "Tôi có thể hoàn toàn tin tưởng vào phương thức jquery html () mà nó sẽ hoạt động giống như innerHTML", câu trả lời của tôi là KHÔNG!

Chạy điều này trong Internet explorer 7 hoặc 8 và bạn sẽ thấy.

jQuery tạo ra HTML không hợp lệ khi đặt HTML có chứa thẻ <FORM> được lồng trong thẻ <P> nơi đầu chuỗi là một dòng mới!

Có một số trường hợp thử nghiệm ở đây và các nhận xét khi chạy phải đủ tự giải thích. Điều này khá mù mờ, nhưng không hiểu chuyện gì đang xảy ra thì hơi bối rối. Tôi sẽ gửi một báo cáo lỗi.

<html>

    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>   

        <script>
            $(function() {

                // the following two blocks of HTML are identical except the P tag is outside the form in the first case
                var html1 = "<p><form id='form1'><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></form></p>";
                var html2 = "<form id='form1'><p><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></p></form>";

                // <FORM> tag nested within <P>
                RunTest("<FORM> tag nested within <P> tag", html1);                 // succeeds in Internet Explorer    
                RunTest("<FORM> tag nested within <P> tag with leading newline", "\n" + html1);     // fails with added new line in Internet Explorer


                // <P> tag nested within <HTML>
                RunTest("<P> tag nested within <FORM> tag", html2);                 // succeeds in Internet Explorer
                RunTest("<P> tag nested within <FORM> tag with leading newline", "\n" + html2);     // succeeds in Internet Explorer even with \n

            });

            function RunTest(testName, html) {

                // run with jQuery
                $("#placeholder").html(html);
                var jqueryDOM = $('#placeholder').html();
                var jqueryFormSerialize = $("#placeholder form").serialize();

                // run with innerHTML
                $("#placeholder")[0].innerHTML = html;

                var innerHTMLDOM = $('#placeholder').html();
                var innerHTMLFormSerialize = $("#placeholder form").serialize();

                var expectedSerializedValue = "field1=111&field2=222";

                alert(  'TEST NAME: ' + testName + '\n\n' +
                    'The HTML :\n"' + html + '"\n\n' +
                    'looks like this in the DOM when assigned with jQuery.html() :\n"' + jqueryDOM + '"\n\n' +
                    'and looks like this in the DOM when assigned with innerHTML :\n"' + innerHTMLDOM + '"\n\n' +

                    'We expect the form to serialize with jQuery.serialize() to be "' + expectedSerializedValue + '"\n\n' +

                    'When using jQuery to initially set the DOM the serialized value is :\n"' + jqueryFormSerialize + '\n' +
                    'When using innerHTML to initially set the DOM the serialized value is :\n"' + innerHTMLFormSerialize + '\n\n' +

                    'jQuery test : ' + (jqueryFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED") + '\n' +
                    'InnerHTML test : ' + (innerHTMLFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED") 

                    );
            }

        </script>
    </head>

    <div id="placeholder">
        This is #placeholder text will 
    </div>

</html>

Tôi nghĩ rằng báo cáo lỗi này quay trở lại khi cho tôi biết rằng tôi có HTML không hợp lệ liên quan đến những gì được phép trong thẻ <P> - hoặc một cái gì đó tương tự. này là khá một thời gian trước vì vậy tôi không chắc chắn nếu bất cứ điều gì thay đổi, nhưng điều này vẫn nhận được upvotes 3 năm sau đó vì vậy nếu ai có bất cứ điều gì thêm xin vui lòng thêm một bình luận
Simon_Weaver

Điều này vẫn còn ở đây trong IE9, chỉ cần thử với cái đó: $ ("body"). Html ("<p> <form> <div> Xem tôi đã làm gì ở đó? </div> </form> </p>" );
Superzadeh

8

Nếu bạn đang thắc mắc về chức năng, thì jQuery's .html()thực hiện cùng một chức năng dự kiến.innerHTML , nhưng nó cũng thực hiện kiểm tra khả năng tương thích giữa các trình duyệt.

Vì lý do này, bạn luôn có thể sử dụng jQuery's .html()thay vì .innerHTMLnếu có thể.


2
innerHTML là một thuộc tính trên tài liệu / thuộc tính phần tử và không phải là một phương thức.
Satish N Ramteare

6

innerHTML không chuẩn và có thể không hoạt động trong một số trình duyệt. Tôi đã sử dụng html () trong tất cả các trình duyệt mà không có vấn đề gì.


3
nó là tiêu chuẩn hiện nay (không biết về thời gian câu hỏi được hỏi): domparsing.spec.whatwg.org/#innerhtml
griffin


3

Với sự hỗ trợ chung của.innerHTML những ngày này, sự khác biệt hiệu quả duy nhất hiện nay là nó .html()sẽ thực thi mã trong bất kỳ <script>thẻ nào nếu có bất kỳ thẻ nào trong html mà bạn cung cấp. .innerHTML, trong HTML5 , sẽ không.

Từ tài liệu jQuery :

Theo thiết kế, bất kỳ hàm tạo hoặc phương thức jQuery nào chấp nhận một chuỗi HTML - jQuery (), .append (),. After (), v.v. - đều có thể thực thi mã. Điều này có thể xảy ra bằng cách chèn các thẻ script hoặc sử dụng các thuộc tính HTML thực thi mã (ví dụ <img onload="">:). Không sử dụng các phương pháp này để chèn các chuỗi thu được từ các nguồn không đáng tin cậy như tham số truy vấn URL, cookie hoặc đầu vào biểu mẫu. Làm như vậy có thể tạo ra các lỗ hổng cross-site-scripting (XSS). Xóa hoặc thoát khỏi bất kỳ đầu vào nào của người dùng trước khi thêm nội dung vào tài liệu.

Lưu ý: cả hai .innerHTML.html()có thể thực thi j theo các cách khác (ví dụ: onerrorthuộc tính).


Rất thú vị. Vậy làm thế nào chúng ta có thể buộc HTML5 thực thi các thẻ <script> khi được chèn vào?
aizquier

Nó hơi cũ nhưng tôi vẫn nghĩ rằng giải pháp của một câu trả lời khác sẽ hoạt động tốt ngày hôm nay. Tất nhiên, bạn có thể chỉ sử dụng .html () nếu bạn đang sử dụng jQuery.
RedRiderX

Bây giờ tôi nhìn lại nó, câu trả lời đó không bỏ lỡ bước phân tích cú pháp scriptthẻ ra khỏi một đoạn html lớn hơn. Có thể một câu hỏi / câu trả lời mới theo thứ tự?
RedRiderX

0

Đây là một số mã để bạn bắt đầu. Bạn có thể sửa đổi hành vi của .innerHTML - thậm chí bạn có thể tạo miếng đệm .innerHTML hoàn chỉnh của riêng mình. (Tái bút: định nghĩa lại .innerHTML cũng sẽ hoạt động trong Firefox, nhưng không hoạt động trên Chrome - họ đang làm việc trên nó.)

if (/(msie|trident)/i.test(navigator.userAgent)) {
 var innerhtml_get = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").get
 var innerhtml_set = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").set
 Object.defineProperty(HTMLElement.prototype, "innerHTML", {
  get: function () {return innerhtml_get.call (this)},
  set: function(new_html) {
   var childNodes = this.childNodes
   for (var curlen = childNodes.length, i = curlen; i > 0; i--) {
    this.removeChild (childNodes[0])
   }
   innerhtml_set.call (this, new_html)
  }
 })
}

var mydiv = document.createElement ('div')
mydiv.innerHTML = "test"
document.body.appendChild (mydiv)

document.body.innerHTML = ""
console.log (mydiv.innerHTML)

http://jsfiddle.net/DLLbc/9/

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.