JQuery html() vs innerHTML

我是否可以完全依赖 jQuery 的 html()方法的行为与 innerHTML相同?innerHTML和 jQuery 的 html()方法有什么区别吗?如果这两个方法都做同样的事情,我可以使用 jQuery 的 html()方法来代替 innerHTML吗?

我的问题是: 我正在处理已经设计好的页面,这些页面包含表格,在 JavaScript 中,innerHTML属性被用来动态填充这些表格。

应用程序在 火狐上正常工作,但是 Internet Explorer触发了一个错误: unknown runtime exception。我使用了 jQuery 的 html()方法,IE的错误消失了。但我不确定它是否适用于所有浏览器,也不确定是否要用 jQuery 的 html()方法替换所有 innerHTML属性。

非常感谢。

185823 次浏览

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

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

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

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.

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

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>

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/

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