jquery .html () vs .append ()

248

Disons que j'ai une div vide:

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

Est-ce:

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

Le même que:

var mySecondDiv=$("<div id='mySecondDiv'></div>");
$('#myDiv').append(mySecondDiv);
Argiropoulos Stavros
la source
21
non, le second n'a pas d'identifiant, donc le même texte ne sera pas affiché.
Matt Ellen
.html est beaucoup plus rapide après sa première exécution. cela peut prendre environ une seconde lorsque vous l'exécutez pour la première fois.
sukhjit dhot

Réponses:

316

Chaque fois que vous passez une chaîne de code HTML à l'une des méthodes de jQuery, voici ce qui se passe:

Un élément temporaire est créé, appelons-le x. x innerHTMLest défini sur la chaîne HTML que vous avez transmise. Ensuite, jQuery transférera chacun des nœuds produits (c'est-à-dire les x childNodes) vers un fragment de document nouvellement créé, qu'il mettra ensuite en cache pour la prochaine fois. Il retournera alors le fragment childNodescomme une nouvelle collection DOM.

Notez que c'est en fait beaucoup plus compliqué que cela, car jQuery fait un tas de vérifications inter-navigateurs et diverses autres optimisations. Par exemple, si vous passez simplement <div></div>à jQuery(), jQuery prendra un raccourci et le fera simplement document.createElement('div').

EDIT : Pour voir la quantité de contrôles que jQuery effectue, jetez un œil ici , ici et ici .


innerHTMLest généralement l'approche la plus rapide, mais ne laissez pas cela régir tout le temps ce que vous faites. L'approche de jQuery n'est pas aussi simple que element.innerHTML = ...- comme je l'ai mentionné, il y a un tas de contrôles et d'optimisations.


La bonne technique dépend fortement de la situation. Si vous souhaitez créer un grand nombre d'éléments identiques, la dernière chose que vous voulez faire est de créer une boucle massive, créant un nouvel objet jQuery à chaque itération. Par exemple, le moyen le plus rapide de créer 100 divs avec jQuery:

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

Il y a aussi des problèmes de lisibilité et de maintenance à prendre en compte.

Ce:

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

... est beaucoup plus difficile à entretenir que cela:

$('<div/>', {
    id: someID,
    className: 'foobar',
    html: content
});
James
la source
5
jQuery (Array (101) .join ('<div> </div>')); <- pourquoi 101 au lieu de 100?
tacone
2
Je voulais juste ajouter un point de données. Faire des tests de performances sur une application qui charge un grand lot (10K +) de <li> dans un <ul> et a vu une augmentation du temps de rendu (pas de chargement) de ~ 12s -> .25s en commutant le .append ( giantListHTMLAsASingleString) à .html (giantListHTMLAsASingleString). Si vous êtes déjà en train de faire l'astuce de «jointure» ou de créer une grosse chaîne html sur votre liste, il y a certainement une différence de performance dans ces deux méthodes.
omnisis
9
@tacone Parce que la "colle" de jonction est appliquée entre les éléments du tableau. 101aura 100 colles appliquées, tout comme se joindre à 3 éléments aurait 2 colles: EL-glue-EL-glue-EL. Dans l'exemple de James, les éléments du tableau sont "vides", donc la jonction de N éléments vides entraîne N-1 colles consécutives.
Fabrício Matté
5
Pour ceux intéressés par une référence pour la syntaxe jquery utilisée ci-dessus et ce qui est autorisé, voir api.jquery.com/jquery/#jQuery-html-attributes .
Thaddeus Albers
1
Il y a une grande différence en ce qu'il perd toutes les données attachées aux doms.
Adrian Bartholomew
68

Ils ne sont pas les mêmes. Le premier remplace le HTML sans créer d'abord un autre objet jQuery. Le second crée un wrapper jQuery supplémentaire pour le deuxième div, puis l' ajoute au premier.

Un jQuery Wrapper (par exemple):

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

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

Deux jQuery Wrappers (par exemple):

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

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

Vous avez plusieurs cas d'utilisation différents en cours. Si vous souhaitez remplacer le contenu, .htmlc'est un excellent appel car c'est l'équivalent de innerHTML = "...". Cependant, si vous souhaitez simplement ajouter du contenu, l' $()ensemble d'enveloppes supplémentaire n'est pas nécessaire.

N'utilisez deux wrappers que si vous devez manipuler l'ajout divultérieurement. Même dans ce cas, vous n'aurez peut-être besoin que d'en utiliser un:

var mySecondDiv = $("<div id='mySecondDiv'></div>").appendTo("#myDiv");
// other code here
mySecondDiv.hide();
Doug Neiner
la source
Tu vois? La concaténation de chaîne laisse déjà une erreur ici (citation non échappée). voir mon post: P
kizzx2
20

si .addvous voulez dire par là .append, le résultat est le même si #myDivest vide.

la performance est-elle la même? ne sais pas.

.html(x) finit par faire la même chose que .empty().append(x)

mkoryak
la source
En outre, le premier aurait évidemment un identifiant de mySecondDiv tandis que l'autre n'aurait aucun identifiant dessus. Et la syntaxe devrait être .html ("<div id = 'mySecondDiv'> </div>") en utilisant des guillemets doubles afin de pouvoir utiliser les guillemets simples.
ryanulit
9

Eh bien, .html()utilise .innerHTMLce qui est plus rapide que la création DOM .

Luca Matteis
la source
7

Vous pouvez obtenir la deuxième méthode pour obtenir le même effet en:

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

Luca a mentionné que html()juste insère le code HTML qui se traduit par des performances plus rapides.

Dans certaines occasions cependant, vous opteriez pour la deuxième option, envisagez:

// 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
la source
5
C'est un code jQuery extrêmement inefficace (et cassé). Si vous voulez éviter la concaténation, faites ceci: (également la note pxn'est pas nécessaire):$('<div />', { width: myWidth }).appendTo("#myDiv");
Doug Neiner
3
Comment est-ce "inutile"? L'affiche a demandé la «différence» (le mot-clé est «vs») alors je lui dis la différence. Le code est verbeux mais je ne dirais pas "inefficace" simplement parce que ce n'est pas un liner. Ne devrions-nous pas être verbeux lorsque nous expliquons des choses aux gens?
kizzx2
3

.html() remplacera tout.

.append() va juste s'ajouter à la fin.

daCoda
la source
2

Autre que les réponses données, dans le cas où vous avez quelque chose comme ça:

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

ce qui signifie que vous voulez ajouter automatiquement un téléchargement de fichier supplémentaire si des fichiers ont été téléchargés, le code mentionné ne fonctionnera pas, car après le téléchargement du fichier, le premier élément de téléchargement de fichier sera recréé et donc le fichier téléchargé sera effacé de celui-ci . Vous devriez utiliser .append () à la place:

    function changed()
    {
        if (isAllowed)
        {
            var tmpHTML = "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
            $('#test').append(tmpHTML);
            isAllowed = false;
        }
    }
Arianbakh
la source
0

Ça m'est arrivé . Version Jquery: 3.3. Si vous parcourez une liste d'objets et souhaitez ajouter chaque objet en tant qu'enfant d'un élément dom parent, alors .html et .append se comporteront très différemment. .htmlfinira par ajouter uniquement le dernier objet à l'élément parent, tandis que .appendtous les objets de liste seront ajoutés en tant qu'enfants de l'élément parent.

Binita Bharati
la source