JQuery html () vs. innerHTML

80

Kann ich mich vollständig darauf verlassen, dass sich die html()Methode von jQuery identisch mit verhält innerHTML? Gibt es einen Unterschied zwischen innerHTMLund der html()Methode von jQuery ? Wenn beide Methoden dasselbe tun, kann ich die html()Methode von jQuery anstelle von verwenden innerHTML?

Mein Problem ist: Ich arbeite an bereits gestalteten Seiten, die Seiten enthalten Tabellen und in JavaScript wird die innerHTMLEigenschaft verwendet, um sie dynamisch zu füllen.

Die Anwendung funktioniert einwandfrei unter Firefox, aber Internet Explorer löst einen Fehler aus : unknown runtime exception. Ich habe die html()Methode von jQuery verwendet und der IE -Fehler ist verschwunden. Ich bin mir jedoch nicht sicher, ob es für alle Browser funktioniert, und ich bin mir nicht sicher, ob alle innerHTMLEigenschaften durch die html()Methode von jQuery ersetzt werden sollen.

Danke vielmals.

Bhupi
quelle
9
Verwenden Sie jQuery html (). Ich hatte bei vielen Gelegenheiten Probleme mit innerHTML. Und html () funktioniert in allen Browsern.
Glavić

Antworten:

116

Zur Beantwortung Ihrer Frage:

.html()ruft nur .innerHTMLnach einigen Überprüfungen für nodeTypes und andere Dinge auf. Es wird auch ein try/catchBlock verwendet, in dem innerHTMLzuerst versucht wird, ihn zu verwenden. Wenn dies fehlschlägt, wird ordnungsgemäß auf jQuery's .empty()+ zurückgegriffenappend()

jAndy
quelle
13
Beachten Sie, dass mit Internet Explorer 8 (und höchstwahrscheinlich früher) die zusätzlichen Überprüfungen einen erheblichen Leistungseinbruch für große Einfügungen bewirken können. Wenn die Leistung im Internet Explorer wichtig ist, sollten Sie die innerHTMLdirekte Verwendung in Betracht ziehen .
sroebuck
3
Ein prägnanter Leistungsvergleich: jsperf.com/innerhtml-vs-html-vs-empty-append
5.
17

Insbesondere in Bezug auf "Kann ich mich vollständig auf die jquery html () -Methode verlassen, die wie innerHTML funktioniert" lautet meine Antwort NEIN!

Führen Sie dies in Internet Explorer 7 oder 8 aus und Sie werden sehen.

jQuery erzeugt fehlerhaftes HTML, wenn HTML festgelegt wird, das ein <FORM> -Tag enthält, das in einem <P> -Tag verschachtelt ist, wobei der Anfang der Zeichenfolge eine neue Zeile ist!

Hier gibt es mehrere Testfälle, und die Kommentare beim Ausführen sollten selbsterklärend genug sein. Das ist ziemlich dunkel, aber nicht zu verstehen, was los ist, ist ein wenig beunruhigend. Ich werde einen Fehlerbericht einreichen.

<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>
Simon_Weaver
quelle
Ich glaube, dieser Fehlerbericht hat mir mitgeteilt, dass ich ungültiges HTML in Bezug auf das hatte, was in einem <P> -Tag erlaubt war - oder so ähnlich. Dies ist eine Weile her, daher bin ich mir nicht sicher, ob sich etwas geändert hat, aber dies wird 3 Jahre später immer noch positiv bewertet. Wenn also jemand etwas hinzuzufügen hat, fügen Sie bitte einen Kommentar hinzu
Simon_Weaver
Dies ist immer noch hier in IE9, versuchen Sie es einfach mit: $ ("body"). Html ("<p> <form> <div> Sehen Sie, was ich dort gemacht habe? </ Div> </ form> </ p>" );
Superzadeh
8

Wenn Sie sich über die Funktionalität wundern, führt jQuery's .html()die gleiche beabsichtigte Funktionalität aus wie .innerHTML, führt jedoch auch Überprüfungen auf browserübergreifende Kompatibilität durch.

Aus diesem Grund können Sie immer jQuery's verwenden, .html()anstatt .innerHTMLwenn möglich.

David Tang
quelle
2
innerHTML ist eine Eigenschaft für die Eigenschaft document / element und keine Methode.
Satish N Ramteare
6

innerHTML ist kein Standard und funktioniert in einigen Browsern möglicherweise nicht. Ich habe html () in allen Browsern ohne Probleme verwendet.

Craig
quelle
3
Es ist jetzt Standard (ich weiß nicht, wann
Griffin
3

In Anbetracht der allgemeinen Unterstützung.innerHTML ist in diesen Tagen, die einzig wirksame Unterschied jetzt, .html()wird Code in irgendwelchen ausführen <script>Tags , wenn es irgendeine in den HTML - Code können Sie es geben. .innerHTML, Unter HTML5 , nicht.

Aus den jQuery-Dokumenten :

Jeder jQuery-Konstruktor oder jede jQuery-Methode, die eine HTML-Zeichenfolge akzeptiert - jQuery (), .append (), .after () usw. - kann möglicherweise Code ausführen. Dies kann durch Einfügen von Skript-Tags oder durch Verwendung von HTML-Attributen geschehen, die Code ausführen (z. B. <img onload="">). Verwenden Sie diese Methoden nicht, um Zeichenfolgen einzufügen, die aus nicht vertrauenswürdigen Quellen stammen, z. B. URL-Abfrageparameter, Cookies oder Formulareingaben. Dies kann zu XSS-Schwachstellen (Cross-Site-Scripting) führen. Entfernen oder entfernen Sie Benutzereingaben, bevor Sie dem Dokument Inhalt hinzufügen.

Hinweis: Beide .innerHTMLund .html()können js auf andere Weise ausführen (z onerror. B. das Attribut).

RedRiderX
quelle
Sehr interessant. Wie können wir HTML5 zwingen, beim Einfügen <script> -Tags auszuführen?
Aizquier
Es ist ein bisschen alt, aber ich denke immer noch, dass die Lösung einer anderen Antwort heute gut funktionieren würde. Sie können natürlich auch einfach .html () verwenden, wenn Sie jQuery verwenden.
RedRiderX
Jetzt, wo ich es mir noch einmal anschaue, verpasst diese Antwort den Schritt des Analysierens von scriptTags aus einem größeren HTML-Fragment. Vielleicht ist eine neue Frage / Antwort angebracht?
RedRiderX
0

Hier ist ein Code, mit dem Sie beginnen können. Sie können das Verhalten von .innerHTML ändern - Sie können sogar Ihren eigenen vollständigen .innerHTML-Shim erstellen. (PS: Die Neudefinition von .innerHTML funktioniert auch in Firefox, aber nicht in Chrome - sie arbeiten daran.)

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/

Agamemnus
quelle