Bhupi
Bhupi

Reputation: 2969

JQuery html() vs. innerHTML

Can I completely rely upon jQuery's html() method behaving identical to innerHTML? Is there any difference between innerHTML and jQuery's html() method? If these methods both do the same, can I use jQuery's html() method in place of innerHTML?

My problem is: I am working on already designed pages, the pages contains tables and in JavaScript the innerHTML property is being used to populate them dynamically.

The application is working fine on Firefox but Internet Explorer fires an error: unknown runtime exception. I used jQuery's html() method and IE's error has disappeared. But I'm not sure it will work for all browsers and I'm not sure whether to replace all innerHTML properties with jQuery's html() method.

Thanks a lot.

Upvotes: 87

Views: 193461

Answers (8)

Justin
Justin

Reputation: 1059

A key difference is that jQuery's .html() method executes any inline <script> tags inside the HTML.

This was key for me as I was using a fetch request to get a response that had HTML that had <script> tags inside as part of making a modal work in WordPress. It wasn't working and I narrowed it down to .html() vs .innerHTML which I thought were identical. After console logging the response and copying it to a file and searching for <script> I found the code that was being run with .html() and not with .innerHTML.

There is also type checking as mentioned by jAndy.

For executing the scripts, check this question linked in the above comments by RedRiderX: how to run javascript in html loaded via ajax


jQuery .html() documentation, which isn't super helpful for this niche question: https://api.jquery.com/html/

Upvotes: 0

David Tang
David Tang

Reputation: 93664

If you're wondering about functionality, then jQuery's .html() performs the same intended functionality as .innerHTML, but it also performs checks for cross-browser compatibility.

For this reason, you can always use jQuery's .html() instead of .innerHTML where possible.

Upvotes: 8

RedRiderX
RedRiderX

Reputation: 354

Given the general support of .innerHTML these days, the only effective difference now is that .html() will execute code in any <script> tags if there are any in the html you give it. .innerHTML, under HTML5, will not.

From the jQuery docs:

By design, any jQuery constructor or method that accepts an HTML string — jQuery(), .append(), .after(), etc. — can potentially execute code. This can occur by injection of script tags or use of HTML attributes that execute code (for example, <img onload="">). Do not use these methods to insert strings obtained from untrusted sources such as URL query parameters, cookies, or form inputs. Doing so can introduce cross-site-scripting (XSS) vulnerabilities. Remove or escape any user input before adding content to the document.

Note: both .innerHTML and .html() can execute js other ways (e.g the onerror attribute).

Upvotes: 7

jAndy
jAndy

Reputation: 235972

To answer your question:

.html() will just call .innerHTML after doing some checks for nodeTypes and stuff. It also uses a try/catch block where it tries to use innerHTML first and if that fails, it'll fallback gracefully to jQuery's .empty() + append()

Upvotes: 125

Agamemnus
Agamemnus

Reputation: 1426

Here is some code to get you started. You can modify the behavior of .innerHTML -- you could even create your own complete .innerHTML shim. (P.S.: redefining .innerHTML will also work in Firefox, but not Chrome -- they're working on it.)

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/

Upvotes: 0

Simon_Weaver
Simon_Weaver

Reputation: 145890

Specifically regarding "Can I rely completely upon jquery html() method that it'll perform like innerHTML" my answer is NO!

Run this in internet explorer 7 or 8 and you'll see.

jQuery produces bad HTML when setting HTML containing a <FORM> tag nested within a <P> tag where the beginning of the string is a newline!

There are several test cases here and the comments when run should be self explanatory enough. This is quite obscure, but not understanding what's going on is a little disconcerting. I'm going to file a bug report.

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

Upvotes: 17

Craig
Craig

Reputation: 36816

innerHTML is not standard and may not work in some browsers. I have used html() in all browsers with no problem.

Upvotes: 6

codersarepeople
codersarepeople

Reputation: 2001

"This method uses the browser's innerHTML property." - jQuery API

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

Upvotes: 3

Related Questions