jQuery Data vs Attr?


513

Qual é a diferença de uso entre $.datae $.attrao usar data-someAttribute?

Meu entendimento é que $.dataé armazenado no jQuery $.cache, não no DOM. Portanto, se eu quiser usar $.cachepara armazenamento de dados, devo usar $.data. Se eu quiser adicionar atributos de dados HTML5, devo usar $.attr("data-attribute", "myCoolValue").



14
@zzz Exceto que realmente não parece responder à pergunta ...?
precisa saber é o seguinte

2
Na verdade, indiretamente. Anexar um objeto via attr()pode levar a vazamentos de memória (pelo menos no IE), enquanto o uso data()é seguro. Ele sugere isso em sua resposta, embora ele não explique explicitamente. Mais informações sobre os documentos do jQuery (consulte as "Notas adicionais"): api.jquery.com/attr
ken

6
@ John B, apenas para sua informação (mesmo que antiga), o atributo data de data-someAttributeé inválido; de acordo com as especificações, somente letras minúsculas são permitidas. Você encontrará uma infinidade de problemas estranhos usando caracteres maiúsculos.
Ken

1
@AdrienBe lote de referências facilmente encontrados através de pesquisa, mas desde que eu estou entediado, aqui vai: stackoverflow.com/a/22753630/84473
ken

Respostas:


748

Se você estiver passando dados para um elemento DOM do servidor, defina os dados no elemento:

<a id="foo" data-foo="bar" href="#">foo!</a>

Os dados podem ser acessados ​​usando .data()no jQuery:

console.log( $('#foo').data('foo') );
//outputs "bar"

No entanto, quando você armazena dados em um nó DOM no jQuery usando dados, as variáveis ​​são armazenadas no objeto do nó . Isso serve para acomodar objetos e referências complexos, pois o armazenamento dos dados no elemento do nó como um atributo acomodará apenas valores de sequência.

Continuando meu exemplo acima:
$('#foo').data('foo', 'baz');

console.log( $('#foo').attr('data-foo') );
//outputs "bar" as the attribute was never changed

console.log( $('#foo').data('foo') );
//outputs "baz" as the value has been updated on the object

Além disso, a convenção de nomenclatura para atributos de dados tem um pouco de "pegadinha" oculto:

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('fooBarBaz') );
//outputs "fizz-buzz" as hyphens are automatically camelCase'd

A chave hifenizada ainda funcionará:

HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('foo-bar-baz') );
//still outputs "fizz-buzz"

No entanto, o objeto retornado por .data()não terá a chave hifenizada definida:

$('#bar').data().fooBarBaz; //works
$('#bar').data()['fooBarBaz']; //works
$('#bar').data()['foo-bar-baz']; //does not work

É por esse motivo que sugiro evitar a chave hifenizada em javascript.

Para HTML, continue usando o formulário hifenizado. Atributos HTML é suposto a obter automaticamente em minúsculas-ASCII , então <div data-foobar></div>, <DIV DATA-FOOBAR></DIV>e <dIv DaTa-FoObAr></DiV>são suposto ser tratados como idênticos, mas para a melhor compatibilidade deve ser preferido a forma minúsculas.

O .data()método também executará alguma conversão automática básica se o valor corresponder a um padrão reconhecido:

HTML:
<a id="foo"
    href="#"
    data-str="bar"
    data-bool="true"
    data-num="15"
    data-json='{"fizz":["buzz"]}'>foo!</a>
JS:
$('#foo').data('str');  //`"bar"`
$('#foo').data('bool'); //`true`
$('#foo').data('num');  //`15`
$('#foo').data('json'); //`{fizz:['buzz']}`

Essa capacidade de transmissão automática é muito conveniente para instanciar widgets e plugins:

$('.widget').each(function () {
    $(this).widget($(this).data());
    //-or-
    $(this).widget($(this).data('widget'));
});

Se você absolutamente precisa ter o valor original como uma string, precisará usar .attr():

HTML:
<a id="foo" href="#" data-color="ABC123"></a>
<a id="bar" href="#" data-color="654321"></a>
JS:
$('#foo').data('color').length; //6
$('#bar').data('color').length; //undefined, length isn't a property of numbers

$('#foo').attr('data-color').length; //6
$('#bar').attr('data-color').length; //6

Este foi um exemplo artificial. Para armazenar valores de cores, eu costumava usar a notação hexadecimal numérica (ou seja, 0xABC123), mas vale a pena notar que o hex foi analisado incorretamente nas versões do jQuery anteriores à 1.7.2 e não é mais analisado no a Numberpartir do jQuery 1.8 rc 1.

O jQuery 1.8 rc 1 mudou o comportamento da conversão automática . Antes, qualquer formato que fosse uma representação válida de a Numberseria convertido em Number. Agora, os valores numéricos só são convertidos automaticamente se sua representação permanecer a mesma. Isso é melhor ilustrado com um exemplo.

HTML:
<a id="foo"
    href="#"
    data-int="1000"
    data-decimal="1000.00"
    data-scientific="1e3"
    data-hex="0x03e8">foo!</a>
JS:
                              // pre 1.8    post 1.8
$('#foo').data('int');        //    1000        1000
$('#foo').data('decimal');    //    1000   "1000.00"
$('#foo').data('scientific'); //    1000       "1e3"
$('#foo').data('hex');        //    1000     "0x03e8"

Se você planeja usar sintaxe numérica alternativa para acessar valores numéricos, certifique-se de converter o valor em um Numberprimeiro, como em um +operador unário .

JS (cont.):
+$('#foo').data('hex'); // 1000

17
@vitorbal, enquanto isso é verdade, o objeto retornado por .data()se não ter o hífen conjunto de formulários, por isso $('#bar').data('foo-bar-baz')vai funcionar, mas $('#bar').data()['foo-bar-baz']não vai. É por esse motivo que sugiro que as pessoas evitem usar o formulário hifenizado.
precisa saber é o seguinte

1
ok, agora entendo o que você quer dizer. Não sabia sobre esse pequeno detalhe, obrigado pela atualização :)
vitorbal

1
@SableFoste, qual link? api.jquery.com/data é o link correto para o método e não mudou até onde eu sei.
precisa saber é o seguinte

1
eu gosto, foo, bar, baz, fizz, buzz: D
Usman Younas

1
Ame cada linha.
Foo Bar

108

A principal diferença entre os dois é onde está armazenado e como é acessado.

$.fn.attr armazena as informações diretamente no elemento em atributos que são publicamente visíveis após a inspeção e também estão disponíveis na API nativa do elemento.

$.fn.dataarmazena as informações em um local ridiculamente obscuro . Ele está localizado em uma variável local fechada sobre chamada, data_userque é uma instância de uma função definida localmente Data. Esta variável não é acessível diretamente de fora do jQuery.

Conjunto de dados com attr()

  • acessível a partir de $(element).attr('data-name')
  • acessível a partir de element.getAttribute('data-name'),
  • se o valor foi na forma de data-nametambém acessível a partir de $(element).data(name)e element.dataset['name']eelement.dataset.name
  • visível no elemento após inspeção
  • não pode ser objetos

Conjunto de dados com .data()

  • acessível apenas a partir de.data(name)
  • não acessível de .attr()ou em qualquer outro lugar
  • não visível ao público no elemento após inspeção
  • pode ser objetos

2
Sim, minha pergunta principal era onde esses dados estavam armazenados, então obrigado por essas informações!
Max Wilder

2
Também .attr()é o caminho a percorrer, se depois você quiser usar a dados como seletor ( .data()não será encontrada; veja codepen.io/anon/pen/EvawPV?editors=1011 )
Kamafeather

1

Você pode usar o data-*atributo para incorporar dados personalizados. Os data-*atributos nos permitem incorporar atributos de dados personalizados em todos os elementos HTML.

O .data()método jQuery permite que você obtenha / defina dados de qualquer tipo para elementos DOM de uma maneira segura de referências circulares e, portanto, de vazamentos de memória.

O .attr()método jQuery obtém / define o valor do atributo apenas para o primeiro elemento no conjunto correspondente.

Exemplo:

<span id="test" title="foo" data-kind="primary">foo</span>

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.