JQuery html () проти innerHTML


81

Чи можу я повністю розраховувати на html()метод jQuery, який поводиться ідентично innerHTML? Чи існує якась різниця між методом innerHTMLjQuery html()? Якщо обидва методи роблять однаково, чи можу я використовувати html()метод jQuery замість innerHTML?

Моя проблема полягає в тому, що я працюю на вже розроблених сторінках, сторінки містять таблиці, а в JavaScript innerHTMLвластивість використовується для їх динамічного заповнення.

Додаток працює відмінно на Firefox , але Internet Explorer запускає помилку: unknown runtime exception. Я використав html()метод jQuery, і помилка IE зникла. Але я не впевнений, що це буде працювати для всіх браузерів, і я не впевнений, чи слід замінювати всі innerHTMLвластивості html()методом jQuery .

Дуже дякую.


9
використовуйте jQuery html (). У мене багато разів були проблеми з innerHTML. А html () буде працювати у всіх браузерах.
Glavić

Відповіді:


118

Щоб відповісти на ваше запитання:

.html()просто зателефонує .innerHTMLпісля перевірки на наявність nodeTypes та інше. Він також використовує try/catchблок, де він намагається використовувати innerHTMLперший, і якщо це не вдається, він елегантно повернеться до jQuery .empty()+append()


13
Зауважте, що в Internet Explorer 8 (і, швидше за все, раніше), додаткові перевірки можуть додати значний показник продуктивності для великих вставок, тому, якщо продуктивність в IE важлива, ви можете розглянути можливість використання innerHTMLбезпосередньо.
sroebuck


17

Зокрема щодо "Чи можу я повністю покластись на метод jquery html (), який буде виконуватись як innerHTML", моя відповідь НІ!

Запустіть це в Internet Explorer 7 або 8, і ви побачите.

jQuery створює поганий HTML при встановленні HTML, що містить тег <FORM>, вкладений у тег <P>, де початком рядка є новий рядок!

Тут є кілька тестових випадків, і коментарі при запуску мають бути досить зрозумілими. Це досить неясно, але незрозуміти, що відбувається, трохи бентежить. Я збираюся подати звіт про помилку.

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

Я думаю, що цей звіт про помилку повернувся як повідомлення про те, що я мав недійсний HTML щодо дозволеного в тегу <P> - або щось подібне. це було досить давно, тому я не впевнений, що щось змінилось, але це все ще зростає за 3 роки потому, якщо хтось має що додати, будь ласка, додайте коментар
Simon_Weaver

Це все ще тут, в IE9, просто спробуйте з цим: $ ("body"). Html ("<p> <form> <div> Подивіться, що я там зробив? </div> </form> </p>" );
Superzadeh

8

Якщо вам цікаво щодо функціональності, тоді jQuery's .html()виконує ті самі функції , що й передбачені.innerHTML , але також перевіряє сумісність між браузерами.

З цієї причини ви завжди можете використовувати jQuery, .html()а не .innerHTMLтам, де це можливо.


2
innerHTML - це властивість властивості документа / елемента, а не метод.
Сатіш Н Рамтеаре,

6

InternalHTML не є стандартним і може не працювати в деяких браузерах. Я без проблем використовував html () у всіх браузерах.


3
це стандарт в даний час (не знаю , про час , питання було поставлене): domparsing.spec.whatwg.org/#innerhtml
грифон


3

З огляду на загальну підтримку в.innerHTML наші дні, єдиною ефективною різницею зараз є те, що код.html() буде виконуватися в будь-яких <script>тегах, якщо такі є в html, який ви йому надаєте. .innerHTML, під HTML5 , не буде.

З документів jQuery :

За дизайном будь-який конструктор або метод jQuery, який приймає рядок HTML - jQuery (), .append (), .after () тощо - потенційно може виконувати код. Це може статися шляхом введення тегів сценарію або використання атрибутів HTML, які виконують код (наприклад, <img onload="">). Не використовуйте ці методи для вставки рядків, отриманих з ненадійних джерел, таких як параметри запиту URL, файли cookie або вводи форми. Це може ввести вразливості міжсайтових сценаріїв (XSS). Видаліть або уникніть будь-якого вводу користувача перед додаванням вмісту в документ.

Примітка: обидва .innerHTMLі .html()можуть виконувати js іншими способами (наприклад, onerrorатрибут).


Дуже цікаво. То як ми можемо змусити HTML5 виконувати теги <script> при вставці?
aizquier

Це трохи застаріло, але я все ще думаю , що рішення іншої відповіді сьогодні спрацювало б добре. Звичайно, ви можете просто використовувати .html (), якщо ви використовуєте jQuery.
RedRiderX

Тепер, коли я ще раз переглядаю його, ця відповідь не пропускає крок синтаксичного аналізу scriptтегів із більшого фрагмента html. Можливо, нове запитання / відповідь в порядку?
RedRiderX

0

Ось декілька кодів для початку. Ви можете змінити поведінку .innerHTML - ви навіть можете створити свій власний цілий .innerHTML шим. (PS: перевизначення .innerHTML також буде працювати у Firefox, але не Chrome - вони працюють над цим.)

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/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.