jquery .html () vs .append ()

248

Powiedzmy, że mam pusty div:

<div id='myDiv'></div>

Czy to jest:

$('#myDiv').html("<div id='mySecondDiv'></div>");

Taki sam jak:

var mySecondDiv=$("<div id='mySecondDiv'></div>");
$('#myDiv').append(mySecondDiv);
Argiropoulos Stavros
źródło
21
nie, drugi nie ma identyfikatora, więc ten sam tekst nie zostanie wydrukowany.
Matt Ellen,
.html jest znacznie szybszy po pierwszym uruchomieniu. może zająć około sekundy przy pierwszym uruchomieniu.
sukhjit dhot

Odpowiedzi:

316

Ilekroć przekazujesz ciąg HTML do dowolnej metody jQuery, dzieje się tak:

Tworzony jest element tymczasowy, nazwijmy go x. x innerHTMLjest ustawiony na ciąg HTML, który przekazałeś. Następnie jQuery prześle każdy z wyprodukowanych węzłów (to znaczy x childNodes) do nowo utworzonego fragmentu dokumentu, który następnie buforuje następnym razem. Zwróci następnie fragment childNodesjako świeżą kolekcję DOM.

Zauważ, że jest to o wiele bardziej skomplikowane, ponieważ jQuery wykonuje wiele kontroli w różnych przeglądarkach i różne inne optymalizacje. Np. Jeśli przejdziesz tylko <div></div>do jQuery(), jQuery weźmie skrót i po prostu zrobi document.createElement('div').

EDYCJA : Aby zobaczyć samą liczbę kontroli wykonywanych przez jQuery, zajrzyj tutaj , tutaj i tutaj .


innerHTMLjest generalnie szybszym podejściem, chociaż nie pozwól, aby to rządziło tym, co robisz przez cały czas. Podejście jQuery nie jest tak proste, jak element.innerHTML = ...- jak już wspomniałem, pojawia się kilka sprawdzeń i optymalizacji.


Prawidłowa technika zależy w dużej mierze od sytuacji. Jeśli chcesz utworzyć dużą liczbę identycznych elementów, ostatnią rzeczą, którą chcesz zrobić, to stworzyć ogromną pętlę, tworząc nowy obiekt jQuery przy każdej iteracji. Np. Najszybszy sposób na utworzenie 100 div za pomocą jQuery:

jQuery(Array(101).join('<div></div>'));

Należy również wziąć pod uwagę kwestie czytelności i konserwacji.

To:

$('<div id="' + someID + '" class="foobar">' + content + '</div>');

... jest o wiele trudniejszy w utrzymaniu niż to:

$('<div/>', {
    id: someID,
    className: 'foobar',
    html: content
});
James
źródło
5
jQuery (Array (101) .join ('<div> </div>')); <- dlaczego 101 zamiast 100?
tacone
2
Chciałem tylko dodać punkt danych. Przeprowadzając pewne testy wydajności w aplikacji, która ładuje dużą (10K +) partię <li> do <ul> i zauważyła wzrost czasu renderowania (nie wczytywania) od ~ 12s -> .25s przez zmianę .append ( giantListHTMLAsASingleString) do .html (giantListHTMLAsASingleString). Jeśli już robisz sztuczkę „dołącz” lub tworzysz duży ciąg HTML na swojej liście, to zdecydowanie różni się ta metoda.
omnisis
9
@tacone Ponieważ łączący „klej” jest nakładany między elementami tablicy. 101będzie miał 100 kleje stosuje się, podobnie jak połączenie elementy 3 musiałby 2 kleje: EL-glue-EL-glue-EL. W przykładzie Jamesa elementy tablicy są „puste”, więc połączenie N pustych elementów daje N-1 kolejnych klejów.
Fabrício Matté
5
Osoby zainteresowane odwołaniem do używanej powyżej składni jquery i dozwolonymi informacjami zobacz api.jquery.com/jquery/#jQuery-html-attributes .
Thaddeus Albers
1
Istnieje duża różnica w tym, że traci wszelkie dane dołączone do domen.
Adrian Bartłomiej
68

One nie są takie same. Pierwszy zastępuje HTML bez uprzedniego utworzenia innego obiektu jQuery. Drugi tworzy dodatkowe opakowanie jQuery dla drugiego div, a następnie dołącza je do pierwszego.

Jedno opakowanie jQuery (na przykład):

$("#myDiv").html('<div id="mySecondDiv"></div>');

$("#myDiv").append('<div id="mySecondDiv"></div>');

Dwa opakowania jQuery (na przykład):

var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').html(mySecondDiv);

var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').append(mySecondDiv);

Trwa kilka różnych przypadków użycia. Jeśli chcesz zastąpić treść, .htmlto świetne połączenie, ponieważ jest to odpowiednik innerHTML = "...". Jeśli jednak chcesz tylko dodać treść, dodatkowy $()zestaw opakowań nie jest potrzebny.

Używaj tylko dwóch opakowań, jeśli chcesz divpóźniej manipulować dodanym . Nawet w takim przypadku może być konieczne użycie tylko jednego:

var mySecondDiv = $("<div id='mySecondDiv'></div>").appendTo("#myDiv");
// other code here
mySecondDiv.hide();
Doug Neiner
źródło
Zobaczysz? Łączenie łańcuchów już pozwoliło na błąd tutaj (cytat bez ukrycia). zobacz mój post: P
kizzx2
20

jeśli .addmasz na myśli .append, to wynik jest taki sam, jeśli #myDivjest pusty.

czy wydajność jest taka sama? nie wiem

.html(x) kończy się tak samo jak .empty().append(x)

mkoryak
źródło
Również pierwszy z nich miałby oczywiście identyfikator mySecondDiv, podczas gdy drugi nie miałby na nim identyfikatora. A składnia musiałaby być .html („<div id = 'mySecondDiv'> </div>”) przy użyciu podwójnych cudzysłowów, aby móc używać pojedynczych cudzysłowów.
ryanulit
9

Cóż, .html()zastosowania, .innerHTMLktóre są szybsze niż tworzenie DOM .

Luca Matteis
źródło
7

Możesz uzyskać drugą metodę osiągnięcia tego samego efektu poprzez:

var mySecondDiv = $('<div></div>');
$(mySecondDiv).find('div').attr('id', 'mySecondDiv');
$('#myDiv').append(mySecondDiv);

Luca wspomniał, że html()po prostu wstawia HTML, co skutkuje większą wydajnością.

Jednak w niektórych przypadkach wybrałbyś drugą opcję, rozważ:

// Clumsy string concat, error prone
$('#myDiv').html("<div style='width:'" + myWidth + "'px'>Lorem ipsum</div>");

// Isn't this a lot cleaner? (though longer)
var newDiv = $('<div></div>');
$(newDiv).find('div').css('width', myWidth);
$('#myDiv').append(newDiv);
kizzx2
źródło
5
Jest to bardzo nieefektywny (i uszkodzony) kod jQuery. Jeśli chcesz uniknąć konkatenacji, zrób to: (uwaga pxnie jest potrzebna):$('<div />', { width: myWidth }).appendTo("#myDiv");
Doug Neiner
3
W jaki sposób jest to „nieprzydatne”? Plakat poprosił o „różnicę” (słowo kluczowe to „vs”), więc powiem mu różnicę. Kod jest pełny, ale nie powiedziałbym, że jest „nieefektywny” tylko dlatego, że nie jest to jedna linijka. Czy nie powinniśmy być gadatliwi, tłumacząc ludziom rzeczy?
kizzx2
3

.html() zastąpi wszystko.

.append() po prostu dopisuje na końcu.

daCoda
źródło
2

Inne niż podane odpowiedzi, jeśli masz coś takiego:

<div id="test">
    <input type="file" name="file0" onchange="changed()">
</div>
<script type="text/javascript">
    var isAllowed = true;
    function changed()
    {
        if (isAllowed)
        {
            var tmpHTML = $('#test').html();
            tmpHTML += "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
            $('#test').html(tmpHTML);
            isAllowed = false;
        }
    }
</script>

co oznacza, że ​​chcesz automatycznie dodać jeszcze jeden plik do przesłania, jeśli jakieś pliki zostały przesłane, wspomniany kod nie będzie działał, ponieważ po przesłaniu pliku zostanie odtworzony pierwszy element do przesłania pliku, a zatem przesłany plik zostanie z niego usunięty . Zamiast tego powinieneś użyć .append ():

    function changed()
    {
        if (isAllowed)
        {
            var tmpHTML = "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
            $('#test').append(tmpHTML);
            isAllowed = false;
        }
    }
Arianbakh
źródło
0

Tak mi się stało. Wersja Jquery: 3.3. Jeśli przeglądasz listę obiektów i chcesz dodać każdy obiekt jako element podrzędny jakiegoś nadrzędnego elementu dom, wówczas pliki .html i .append będą się zachowywać zupełnie inaczej. .htmlw końcu doda tylko ostatni obiekt do elementu nadrzędnego, podczas gdy .appenddoda wszystkie obiekty listy jako elementy podrzędne elementu nadrzędnego.

Binita Bharati
źródło