javascript - custom - jQuery Data vs Attr?
get data value javascript (2)
La principal diferencia entre los dos es dónde se almacena y cómo se accede.
api.jquery.com/attr almacena la información directamente en el elemento en atributos que son públicamente visibles tras la inspección, y también que están disponibles en la API nativa del elemento.
$.fn.data
almacena la información en un lugar ridículamente oscuro . Se encuentra en una variable local cerrada sobre datos llamada data_user
que es una instancia de una función definida localmente Data. Esta variable no es accesible directamente desde fuera de jQuery.
Conjunto de datos con attr()
- accesible desde
$(element).attr(''data-name'')
- accesible desde
element.getAttribute(''data-name'')
, - si el valor estaba en la forma de
data-name
dedata-name
también se puede acceder desde$(element).data(name)
yelement.dataset[''name'']
yelement.dataset.name
- visible en el elemento tras la inspección
- no pueden ser objetos
Conjunto de datos con .data()
- accesible solo desde
.data(name)
- no accesible desde
.attr()
o desde cualquier otro lugar - no visible públicamente en el elemento después de la inspección
- pueden ser objetos
¿Cuál es la diferencia de uso entre $.data
y $.attr
cuando se usa data-someAttribute
?
Mi entendimiento es que $.data
se almacena dentro de $.cache
jQuery, no en el DOM. Por lo tanto, si quiero usar $.cache
para el almacenamiento de datos, debería usar $.data
. Si quiero agregar atributos de datos HTML5, debería usar $.attr("data-attribute", "myCoolValue")
.
Si está pasando datos a un elemento DOM desde el servidor, debe establecer los datos en el elemento:
<a id="foo" data-foo="bar" href="#">foo!</a>
Se puede acceder a los datos usando .data()
en jQuery:
console.log( $(''#foo'').data(''foo'') );
//outputs "bar"
Sin embargo, cuando almacena datos en un nodo DOM en jQuery utilizando datos, las variables se almacenan en el objeto de nodo. Esto es para acomodar objetos complejos y referencias, ya que almacenar los datos en el elemento nodo como un atributo solo acomodará valores de cadena.
Continuando mi ejemplo desde arriba:$(''#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
Además, la convención de nomenclatura para atributos de datos tiene un poco de "gotcha" oculta:
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
La clave con guión todavía 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"
Sin embargo, el objeto devuelto por .data()
no tendrá el conjunto de claves con guión:
$(''#bar'').data().fooBarBaz; //works
$(''#bar'').data()[''fooBarBaz'']; //works
$(''#bar'').data()[''foo-bar-baz'']; //does not work
Es por esta razón que sugiero evitar la clave con guión en javascript.
Para HTML, siga utilizando el formulario con guión. Se supone que los atributos HTML se bajan en ASCII automáticamente , por lo que <div data-foobar></div>
, <DIV DATA-FOOBAR></DIV>
y <dIv DaTa-FoObAr></DiV>
deben tratarse como idéntico, pero para la mejor compatibilidad se debe preferir la forma en minúsculas.
El método .data()
también realizará una conversión automática básica si el valor coincide con un patrón reconocido:
<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'']}`
Esta capacidad de conversión automática es muy conveniente para la creación de widgets y complementos:
$(''.widget'').each(function () {
$(this).widget($(this).data());
//-or-
$(this).widget($(this).data(''widget''));
});
Si absolutamente debe tener el valor original como una cadena, entonces necesitará usar .attr()
:
<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 fue un ejemplo artificial. Para almacenar valores de color, solía usar la notación hexadecimal numérica (es decir, 0xABC123), pero vale la pena señalar que el hex fue analizado incorrectamente en las versiones de jQuery antes de 1.7.2 , y ya no se analiza en un Number
desde jQuery 1.8 rc 1
jQuery 1.8 rc 1 cambió el comportamiento del auto-casting . Antes, cualquier formato que fuera una representación válida de un Number
se convertiría en Number
. Ahora, los valores que son numéricos solo se convierten automáticamente si su representación sigue siendo la misma. Esto se ilustra mejor con un ejemplo.
<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"
Si planea usar sintaxis numéricas alternativas para acceder a valores numéricos, asegúrese de convertir el valor en un Number
primero, como con un operador unario +
.
+$(''#foo'').data(''hex''); // 1000