Quando é melhor usar .data () ou .attr ()?

Acho que todo mundo, uma vez na vida, fez esta pergunta ao lidar pela primeira vez com jQuery (ou estruturas semelhantes):

Quando é melhor usar .data () e quando é melhor .attr ()?

A resposta não é tão simples e requer algumas explicações.
Vamos ver o que a documentação do jQuery diz sobre esses 2 métodos:

.dados()

Armazena dados arbitrários associados ao elemento especificado e / ou retorna o valor que foi definido.

e

.attr ()

Obtenha o valor de um atributo para o primeiro elemento no conjunto de elementos correspondidos ou defina um ou mais atributos para cada elemento correspondido.

Qual é a diferença?

Basicamente, o método .attr () tem uma influência direta no DOM , então ele obterá os dados do HTML atual ou alterará o código HTML se usado para alterar um valor de atributo. Ao contrário, o método .data () obterá os dados do cache interno e alterará esses dados se um conjunto for chamado, nenhuma manipulação DOM é feita aqui. Outra diferença é que o método .data () requer um prefixo ‘data-‘ para funcionar, por exemplo, se eu quiser passar um atributo de dados chamado foo com bar como valor, preciso codificar: data-foo="bar"e chamar $('#item').data('foo')para obter o valor.

Como eu disse, o armazenamento de dados no cache interno não é visível dentro do DOM (por exemplo, inspecionando o elemento usando o navegador), isso significa que se tivermos um atributo e o alterarmos usando .attr (), seu valor será recuperado com. data () será igual ao original. Ok, provavelmente esta parte é um pouco confusa. Fiz um pequeno código no JSFiddle que ajuda a entendê-lo.data-foo

No meu exemplo, há um div simples:

<div id="item" data-foo="bar">
</div>

O div chamado itemtem um atributo que editaremos de 2 maneiras, com .attr () e com .data (). O resultado é o seguinte:data-foo

data-foo from data(): bar
data
-foo from attr(): bar
-
data changed to bar2

-
data
-foo from data(): bar2
data
-foo from attr(): bar
-
<div id="item" data-foo="bar"> </div>
-
attribute changed to bar3

-
data
-foo from data(): bar2
data
-foo from attr(): bar3
-
<div id="item" data-foo="bar3"> </div>

Conforme explicado antes, chamar .data () para definir algo não manipulará o arquivo dom e chamar .attr () para alterar o atributo não alterará os dados dentro do cache interno.
Isso significa que não podemos alterar um atributo usando .attr () e esperando que os dados retornem de uma chamada .data ().

Ok, agora está um pouco mais claro, mas onde .data () é melhor que .attr () ou vice-versa?

Agora que as diferenças entre .data () e .attr () estão claras, podemos entender quando é melhor usar .attr () e quando é melhor usar .data ().

Um bom uso da chamada .data () é quando um valor é passado para o cliente do servidor que renderiza uma página. Por exemplo, se tivermos um aplicativo da web que precisa passar o valor de foopara o cliente, dentro de nosso mecanismo de renderização teremos algo como:

<div data-foo='<%=item.foo%>'>

Uma boa vantagem de .data () sobre .attr () é que as variáveis ​​são armazenadas no objeto do , portanto, podemos armazenar objetos complexos, não apenas valores de string. Portanto, isso significa que .data () é a melhor maneira de armazenar dados quando temos que obter / definir dados relativos ao estado atual de nosso aplicativo.

A chamada .attr () é melhor quando estamos lidando com mudanças na árvore DOM que terão uma influência direta na marcação , por exemplo, se tivermos que lidar com uma caixa de seleção onde o atributo ‘marcado’ mostrará realmente essa caixa de seleção como verificado na IU. Exemplo no JSFiddle .

Eu acho que é isso!