JQuery html () a innerHTML


81

Czy mogę całkowicie polegać na html()metodzie jQuery zachowującej się identycznie jak innerHTML? Czy jest jakaś różnica między metodą innerHTMLi jQuery html()? Jeśli obie te metody robią to samo, czy mogę użyć html()metody jQuery zamiast innerHTML?

Mój problem polega na tym, że pracuję na już zaprojektowanych stronach, strony zawierają tabele, aw JavaScript innerHTMLwłaściwość jest używana do ich dynamicznego wypełniania.

Aplikacja działa poprawnie na Firefox ale Internet Explorer odpala błąd: unknown runtime exception. Użyłem html()metody jQuery i błąd IE zniknął. Ale nie jestem pewien, czy zadziała we wszystkich przeglądarkach i nie jestem pewien, czy zastąpić wszystkie innerHTMLwłaściwości html()metodą jQuery .

Wielkie dzięki.


9
użyj jQuery html (). Wielokrotnie miałem problemy z innerHTML. A html () będzie działać we wszystkich przeglądarkach.
Glavić,

Odpowiedzi:


118

Odpowiedzieć na Twoje pytanie:

.html()po prostu zadzwoni .innerHTMLpo sprawdzeniu typów węzłów i innych rzeczy. Używa również try/catchbloku, w którym próbuje użyć jako innerHTMLpierwszy, a jeśli to się nie powiedzie, z wdziękiem powróci do .empty()+append()


13
Zauważ, że w przypadku Internet Explorera 8 (i najprawdopodobniej wcześniej) dodatkowe testy mogą znacząco wpłynąć na wydajność dużych wstawek, więc jeśli wydajność w IE jest ważna, możesz rozważyć użycie innerHTMLbezpośrednio.
sroebuck

3
Zwięzłe porównanie wydajności: jsperf.com/innerhtml-vs-html-vs-empty-append
thdoan

17

W szczególności w odniesieniu do „Czy mogę całkowicie polegać na metodzie jquery html (), która będzie działać jak innerHTML”, moja odpowiedź brzmi NIE!

Uruchom to w programie Internet Explorer 7 lub 8, a zobaczysz.

jQuery generuje zły kod HTML podczas ustawiania kodu HTML zawierającego tag <FORM> zagnieżdżony w tagu <P>, gdzie początek ciągu jest znakiem nowej linii!

Jest tutaj kilka przypadków testowych, a komentarze po uruchomieniu powinny być wystarczająco zrozumiałe. Jest to dość niejasne, ale niezrozumienie tego, co się dzieje, jest trochę niepokojące. Mam zamiar zgłosić błąd.

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

Myślę, że ten raport o błędzie wrócił, mówiąc mi, że mam nieprawidłowy kod HTML w odniesieniu do tego, co jest dozwolone w tagu <P> - lub coś w tym rodzaju. to było dość dawno, więc nie jestem pewien, czy coś się zmieniło, ale 3 lata później wciąż pojawiają się głosy, więc jeśli ktoś ma coś do dodania, dodaj komentarz
Simon_Weaver

To jest nadal w IE9, po prostu spróbuj z tym: $ ("body"). Html ("<p> <form> <div> Widzisz, co tam zrobiłem? </div> </form> </p>" );
Superzadeh

8

Jeśli zastanawiasz się nad funkcjonalnością, to jQuery .html()wykonuje te same zamierzone funkcje co .innerHTML, ale sprawdza również zgodność z różnymi przeglądarkami.

Z tego powodu zawsze możesz użyć jQuery .html()zamiast .innerHTMLtam, gdzie to możliwe.


2
innerHTML jest właściwością dokumentu / elementu, a nie metodą.
Satish N Ramteare



3

Biorąc pod uwagę ogólne wsparcie w.innerHTML dzisiejszych czasach, jedyną skuteczną różnicą jest teraz to, że .html()będzie wykonywał kod w dowolnych <script>tagach, jeśli są jakieś w podanym html. .innerHTML, Pod HTML5 , nie będzie.

Z dokumentacji jQuery :

Z założenia każdy konstruktor lub metoda jQuery, która akceptuje ciąg znaków HTML - jQuery (), .append (), .after () itd. - może potencjalnie wykonać kod. Może to nastąpić przez wstrzyknięcie znaczników skryptów lub użycie atrybutów HTML, które wykonują kod (na przykład <img onload="">). Nie używaj tych metod do wstawiania ciągów uzyskanych z niezaufanych źródeł, takich jak parametry zapytań URL, pliki cookie lub dane wejściowe formularzy. Może to spowodować powstanie luk w zabezpieczeniach cross-site-scripting (XSS). Usuń wszelkie dane wejściowe użytkownika lub usuń je przed dodaniem treści do dokumentu.

Uwaga: oba .innerHTMLi .html()mogą wykonywać js w inny sposób (np. onerrorAtrybut).


Bardzo interesujące. Jak więc możemy zmusić HTML5 do wykonywania tagów <script> po wstawieniu?
aizquier

Jest trochę stary, ale nadal uważam, że rozwiązanie innej odpowiedzi działałoby dzisiaj dobrze. Jeśli używasz jQuery, możesz oczywiście po prostu użyć .html ().
RedRiderX

Teraz, gdy spojrzę na to ponownie, w tej odpowiedzi brakuje kroku parsowania scripttagów z większego fragmentu html. Może potrzebne jest nowe pytanie / odpowiedź?
RedRiderX

0

Oto kod na dobry początek. Możesz modyfikować zachowanie .innerHTML - możesz nawet stworzyć własną kompletną podkładkę .innerHTML. (PS: przedefiniowanie .innerHTML będzie działać również w przeglądarce Firefox, ale nie w Chrome - pracują nad tym).

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/

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.