jquery .html () vs .append ()

248

Digamos que eu tenho uma div vazia:

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

É isto:

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

O mesmo que:

var mySecondDiv=$("<div id='mySecondDiv'></div>");
$('#myDiv').append(mySecondDiv);
Argiropoulos Stavros
fonte
21
não, o segundo não possui um ID; portanto, o mesmo texto não será gerado.
Matt Ellen
.html é muito mais rápido depois que você o executa pela primeira vez. pode demorar alguns segundos quando você o executa pela primeira vez.
sukhjit dhot

Respostas:

316

Sempre que você passa uma string de HTML para qualquer método do jQuery, é o que acontece:

Um elemento temporário é criado, vamos chamá-lo de x. x innerHTMLé definido como a string de HTML que você passou. O jQuery transferirá cada um dos nós produzidos (ou seja, x childNodes) para um fragmento de documento recém-criado, que será armazenado em cache na próxima vez. Ele retornará o fragmento childNodescomo uma nova coleção DOM.

Observe que na verdade é muito mais complicado que isso, pois o jQuery faz várias verificações em vários navegadores e várias outras otimizações. Por exemplo, se você passar apenas <div></div>para jQuery(), o jQuery pegará um atalho e simplesmente o fará document.createElement('div').

EDIT : Para ver a grande quantidade de verificações que o jQuery executa, dê uma olhada aqui , aqui e aqui .


innerHTMLgeralmente é a abordagem mais rápida, embora não deixe que governe o que você faz o tempo todo. A abordagem do jQuery não é tão simples quanto element.innerHTML = ...- como mencionei, existem várias verificações e otimizações.


A técnica correta depende muito da situação. Se você deseja criar um grande número de elementos idênticos, a última coisa que você quer fazer é criar um loop massivo, criando um novo objeto jQuery em cada iteração. Por exemplo, a maneira mais rápida de criar 100 divs com jQuery:

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

Também há questões de legibilidade e manutenção a serem levadas em consideração.

Este:

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

... é muito mais difícil de manter do que isso:

$('<div/>', {
    id: someID,
    className: 'foobar',
    html: content
});
James
fonte
5
jQuery (Array (101) .join ('<div> </div>')); <- por que 101 em vez de 100?
Tacone
2
Só queria adicionar um ponto de dados. Fazendo alguns testes de desempenho em um aplicativo que carrega um lote grande (10K +) de <li> em um <ul> e viu um aumento no tempo de renderização (não carregar) de ~ 12s -> .25s alternando o .append ( giantListHTMLAsASingleString) para .html (giantListHTMLAsASingleString). Se você já está praticando o truque de 'junção' ou construindo uma grande string html na sua lista, há definitivamente uma diferença de desempenho nesses dois métodos.
Omnisis
9
@tacone Porque a "cola" de união é aplicada entre os elementos da matriz. 101terá 100 colas aplicadas, assim como juntar 3 elementos teria 2 colas: EL-glue-EL-glue-EL. No exemplo de James, os elementos da matriz estão "vazios", portanto, unir N elementos vazios resulta em colas N-1 consecutivas.
Fabrício Matté 23/08
5
Para os interessados ​​em uma referência para a sintaxe jquery usada acima e o que é permitido, consulte api.jquery.com/jquery/#jQuery-html-attributes .
Thaddeus Albers
1
Há uma grande diferença, pois perde todos os dados anexados aos doms.
Adrian Bartholomew
68

Eles não são os mesmos. O primeiro substitui o HTML sem criar outro objeto jQuery primeiro. O segundo cria um wrapper jQuery adicional para a segunda div e depois o anexa à primeira.

Um Wrapper jQuery (por exemplo):

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

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

Dois Wrappers jQuery (por exemplo):

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

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

Você tem alguns casos de uso diferentes em andamento. Se você deseja substituir o conteúdo, .htmlé uma ótima opção, pois é o equivalente a innerHTML = "...". No entanto, se você quiser apenas acrescentar conteúdo, o $()conjunto adicional de wrapper não será necessário.

Use apenas dois invólucros se precisar manipular os itens adicionados divposteriormente. Mesmo nesse caso, você ainda precisará usar apenas um:

var mySecondDiv = $("<div id='mySecondDiv'></div>").appendTo("#myDiv");
// other code here
mySecondDiv.hide();
Doug Neiner
fonte
Entende? A concatenação de strings já causou um erro aqui (aspas sem escape). veja meu post: P
kizzx2
20

se .addvocê quer dizer .append, então o resultado é o mesmo se #myDivestiver vazio.

o desempenho é o mesmo? não sei.

.html(x) acaba fazendo a mesma coisa que .empty().append(x)

mkoryak
fonte
Além disso, o primeiro obviamente teria um ID de mySecondDiv, enquanto o outro não teria nenhum ID. E a sintaxe precisaria ser .html ("<div id = 'mySecondDiv'> </div>") usando aspas duplas para poder usar aspas simples.
ryanulit
9

Bem, .html()usos .innerHTMLmais rápidos que a criação do DOM .

Luca Matteis
fonte
7

Você pode obter o segundo método para obter o mesmo efeito:

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

Luca mencionou que html()apenas insere o HTML, o que resulta em um desempenho mais rápido.

Em algumas ocasiões, você optaria pela segunda opção, considere:

// 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
fonte
5
Este é um código jQuery extremamente ineficiente (e quebrado). Se você quiser evitar a concatenação, faça o seguinte: (também pxnão é necessário observar ):$('<div />', { width: myWidth }).appendTo("#myDiv");
Doug Neiner 10/10/10
3
Como isso "não é útil"? O pôster pediu a "diferença" (a palavra-chave é "vs"), então eu digo a ele a diferença. O código é detalhado, mas eu não diria "ineficiente" apenas pelo fato de não ser um liner. Não deveríamos ser detalhados ao explicar coisas para as pessoas?
kizzx2
3

.html() irá substituir tudo.

.append() basta acrescentar no final.

daCoda
fonte
2

Além das respostas fornecidas, no caso de você ter algo parecido com isto:

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

o que significa que você deseja adicionar automaticamente mais um upload de arquivo, se algum arquivo tiver sido carregado, o código mencionado não funcionará, porque após o upload do arquivo, o primeiro elemento de upload do arquivo será recriado e, portanto, o arquivo enviado será apagado dele. . Você deve usar .append ():

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

Isso aconteceu comigo. Versão Jquery: 3.3. Se você estiver percorrendo uma lista de objetos e quiser adicionar cada objeto como filho de algum elemento pai dom, então .html e .append se comportarão muito diferentes. .htmlacabará adicionando apenas o último objeto ao elemento pai, enquanto .appendadicionará todos os objetos da lista como filhos do elemento pai.

Binita Bharati
fonte