JQuery html() против innerHTML

Могу ли я полностью полагаться на то, что метод jQuery html() ведет себя так же, как innerHTML? Есть ли разница между методом innerHTML и jQuery html()? Если оба эти метода делают одно и то же, могу ли я использовать метод jQuery html() вместо innerHTML?

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

Приложение нормально работает в Firefox, но Internet Explorer выдает ошибку: unknown runtime exception. Я использовал метод jQuery html(), и ошибка IE исчезла. Но я не уверен, что это будет работать для всех браузеров, и я не уверен, следует ли заменить все свойства innerHTML методом jQuery html().

Большое спасибо.


person Bhupi    schedule 25.08.2010    source источник
comment
используйте jQuery html(). У меня были проблемы с innerHTML во многих случаях. И html() будет работать во всех браузерах.   -  person Glavić    schedule 25.08.2010


Ответы (7)


Чтобы ответить на ваш вопрос:

.html() просто вызовет .innerHTML после проверки типов узлов и прочего. Он также использует блок try/catch, где сначала пытается использовать innerHTML, и если это не удается, он изящно возвращается к jQuery .empty() + append().

person jAndy    schedule 25.08.2010
comment
Обратите внимание, что в Internet Explorer 8 (и, скорее всего, в более ранних версиях) дополнительные проверки могут значительно снизить производительность для больших вставок, поэтому, если производительность в IE важна, вы можете рассмотреть возможность использования innerHTML напрямую. - person sroebuck; 31.08.2012
comment
Краткое сравнение производительности: jsperf.com/innerhtml-vs-html-vs-empty. -добавить - person thdoan; 05.05.2015

В частности, в отношении «Могу ли я полностью полагаться на метод 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>
person Simon_Weaver    schedule 22.11.2010
comment
Я думаю, что этот отчет об ошибке вернулся, говоря мне, что у меня неверный HTML в отношении того, что разрешено в теге ‹P› или что-то в этом роде. это было довольно давно, поэтому я не уверен, что что-то изменилось, но это все еще получает голоса спустя 3 года, поэтому, если у кого-то есть что добавить, пожалуйста, добавьте комментарий - person Simon_Weaver; 16.10.2013
comment
Это все еще здесь, в IE9, просто попробуйте с этим: - person Superzadeh; 12.03.2014

Если вас интересуют функциональные возможности, то .html() jQuery выполняет те же предполагаемые функции, что и .innerHTML, но также выполняет проверки совместимости между браузерами.

По этой причине вы всегда можете использовать jQuery .html() вместо .innerHTML, где это возможно.

person David Tang    schedule 25.08.2010
comment
innerHTML — это свойство документа/элемента, а не метод. - person Satish N Ramteare; 18.04.2019

innerHTML не является стандартным и может не работать в некоторых браузерах. Я использовал html() во всех браузерах без проблем.

person Craig    schedule 25.08.2010
comment
теперь это стандарт (не знаю, когда был задан вопрос): domparsing.spec.whatwg .org/#innerhtml - person griffin; 01.10.2013

«Этот метод использует свойство innerHTML браузера». - jQuery-API

http://api.jquery.com/html/

person codersarepeople    schedule 25.08.2010

Учитывая общую поддержку .innerHTML в наши дни, единственное реальное отличие состоит в том, что .html() будет < strong>выполнять код в любых <script> тегах, если они есть в html, который вы ему даете. .innerHTML, под HTML5, не будет.

Из документов jQuery:

По замыслу любой конструктор или метод jQuery, который принимает строку HTML — jQuery(), .append(), .after() и т. д. — потенциально может выполнять код. Это может произойти путем внедрения тегов сценария или использования атрибутов HTML, которые выполняют код (например, <img onload="">). Не используйте эти методы для вставки строк, полученных из ненадежных источников, таких как параметры запроса URL, файлы cookie или входные данные формы. Это может привести к уязвимостям межсайтового скриптинга (XSS). Удалите или экранируйте любой пользовательский ввод перед добавлением содержимого в документ.

Примечание: как .innerHTML, так и .html() могут выполнять js другими способами (например, атрибут onerror).

person RedRiderX    schedule 11.05.2018
comment
Очень интересно. Итак, как мы можем заставить HTML5 выполнять теги ‹script› при их вставке? - person aizquier; 29.05.2018
comment
Это немного устарело, но я все еще думаю, что другое решение ответа сегодня хорошо сработает. Конечно, вы можете просто использовать .html(), если вы используете jQuery. - person RedRiderX; 06.06.2018
comment
Теперь, когда я снова смотрю на это, в этом ответе отсутствует этап разбора тегов script из большего фрагмента html. Может быть, нужен новый вопрос/ответ? - person RedRiderX; 06.06.2018

Вот некоторый код, чтобы вы начали. Вы можете изменить поведение .innerHTML — вы даже можете создать собственную полную оболочку .innerHTML. (P.S.: переопределение .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/

person Agamemnus    schedule 21.01.2014