jquery - selectores - Selección de elemento por atributo de datos
selector por atributo jquery (11)
Ejemplos nativos de JS
Obtener NodeList de elementos
var elem = document.querySelectorAll(''[data-id="container"]'')
html: <div data-id="container"></div>
Consigue el primer elemento
var firstElem = document.querySelectorAll(''[id="container"]'')[0]
html: <div id="container"></div>
Apunta a una colección de nodos que devuelve una lista de nodos.
document.getElementById(''footer'').querySelectorAll(''[data-id]'')
html:
<div class="footer">
<div data-id="12"></div>
<div data-id="22"></div>
</div>
Obtener elementos basados en múltiples valores de datos (OR)
document.querySelectorAll(''[data-section="12"],[data-selection="20"]'')
html:
<div data-selection="20"></div>
<div data-section="12"></div>
Obtener elementos basados en valores de datos combinados (AND)
document.querySelectorAll(''[data-prop1="12"][data-prop2="20"]'')
html:
<div data-prop1="12" data-prop2="20"></div>
Obtener elementos donde el valor comienza con
document.querySelectorAll(''[href^="https://"]'')
¿Existe un método sencillo y directo para seleccionar elementos según su atributo de data
? Por ejemplo, seleccione todos los anclajes que tengan un atributo de datos llamado customerID
que tenga un valor de 22
.
Soy un poco reacio a usar rel
u otros atributos para almacenar dicha información, pero me resulta mucho más difícil seleccionar un elemento en función de los datos almacenados en él.
A veces es deseable filtrar elementos en función de si tienen elementos de datos adjuntos a ellos mediante programación (también conocido como no a través de atributos dom):
$el.filter(function(i, x) { return $(x).data(''foo-bar''); }).doSomething();
Lo anterior funciona pero no es muy legible. Un mejor enfoque es usar un pseudo-selector para probar este tipo de cosas:
$.expr[":"].hasData = $.expr.createPseudo(function (arg) {
return function (domEl) {
var $el = $(domEl);
return $el.is("[" + ((arg.startsWith("data-") ? "" : "data-") + arg) + "]") || typeof ($el.data(arg)) !== "undefined";
};
});
Ahora podemos refactorizar la declaración original a algo más fluido y legible:
$el.filter(":hasData(''foo-bar'')").doSomething();
El uso de $(''[data-whatever="myvalue"]'')
seleccionará cualquier cosa con atributos html, pero en jQueries más recientes parece que si usa $(...).data(...)
para adjuntar datos, usa algo del navegador mágico y no afecta el html, por lo tanto, no lo descubre .find
como se indica en la respuesta anterior .
Verificar (probado con 1.7.2+) (también ver fiddle ): (actualizado para ser más completo)
var $container = $(''<div><div id="item1"/><div id="item2"/></div>'');
// add html attribute
var $item1 = $(''#item1'').attr(''data-generated'', true);
// add as data
var $item2 = $(''#item2'').data(''generated'', true);
// create item, add data attribute via jquery
var $item3 = $(''<div />'', {id: ''item3'', data: { generated: ''true'' }, text: ''Item 3'' });
$container.append($item3);
// create item, "manually" add data attribute
var $item4 = $(''<div id="item4" data-generated="true">Item 4</div>'');
$container.append($item4);
// only returns $item1 and $item4
var $result = $container.find(''[data-generated="true"]'');
La construcción como esta: $(''[data-XXX=111]'')
no funciona en Safari 8.0 .
Si configura el atributo de datos de esta manera: $(''div'').data(''XXX'', 111)
, solo funciona si configura el atributo de datos directamente en DOM como este: $(''div'').attr(''data-XXX'', 111)
.
Creo que es porque el equipo de jQuery optimizó el recolector de basura para evitar pérdidas de memoria y operaciones pesadas en la reconstrucción de DOM en cada atributo de datos de cambio.
No he visto una respuesta de JavaScript sin jQuery. Esperemos que ayude a alguien.
var elements = document.querySelectorAll(''[data-customerID="22"]'');
elements[0].innerHTML = ''it worked!'';
<a data-customerID=''22''>test</a>
Información:
Para las personas que buscan en Google y desean más reglas generales sobre la selección con atributos de datos:
$("[data-test]")
seleccionará cualquier elemento que simplemente tenga el atributo de datos (sin importar el valor del atributo). Incluso:
<div data-test=value>attributes with values</div>
<div data-test>attributes without values</div>
$(''[data-test~="foo"]'')
seleccionará cualquier elemento en el que el atributo de datos contenga foo
pero no tenga que ser exacto, como:
<div data-test="foo">Exact Matches</div>
<div data-test="this has the word foo">Where the Attribute merely contains "foo"</div>
$(''[data-test="the_exact_value"]'')
seleccionará cualquier elemento donde el valor exacto del atributo de datos sea the_exact_value
, por ejemplo:
<div data-test="the_exact_value">Exact Matches</div>
pero no
<div data-test="the_exact_value foo">This won''t match</div>
Para que esto funcione en Chrome, el valor no debe tener otro par de comillas.
Solo funciona, por ejemplo, así:
$(''a[data-customerID=22]'');
Para seleccionar todos los anclajes con el atributo de data-customerID==22
, debe incluir la a
para limitar el alcance de la búsqueda solo a ese tipo de elemento. Hacer búsquedas de atributos de datos en un bucle grande o en alta frecuencia cuando hay muchos elementos en la página puede causar problemas de rendimiento.
$(''a[data-customerID="22"]'');
Solo para completar todas las respuestas con algunas características del ''estándar de vida'': a estas alturas (en la era html5) es posible hacerlo sin una biblioteca de terceros:
- JS puro / simple con querySelector (utiliza selectores de CSS):
- seleccione el primero en DOM:
document.querySelector(''[data-answer="42"],[type="submit"]'')
- seleccione todo en DOM:
document.querySelectorAll(''[data-answer="42"],[type="submit"]'')
- seleccione el primero en DOM:
- CSS puro / plano
- algunas etiquetas específicas:
[data-answer="42"],[type="submit"]
- todas las etiquetas con un atributo específico:
[data-answer]
oinput[type]
- algunas etiquetas específicas:
a través del método Jquery filter ():
http://jsfiddle.net/9n4e1agn/1/
HTML:
<button data-id=''1''>One</button>
<button data-id=''2''>Two</button>
JavaScript:
$(function() {
$(''button'').filter(function(){
return $(this).data("id") == 2}).css({background:''red''});
});
$(''*[data-customerID="22"]'');
Debería poder omitir el *
, pero si recuerdo correctamente, dependiendo de la versión de jQuery que esté usando, esto podría dar resultados erróneos.
Tenga en cuenta que para la compatibilidad con la API de selectores ( document.querySelector{,all}
), las comillas en torno al valor del atributo ( 22
) no se pueden omitir en este caso .
Además, si trabaja mucho con los atributos de datos en sus scripts jQuery, es posible que desee considerar el uso del complemento de atributos de datos personalizados HTML5 . Esto le permite escribir un código aún más legible usando .dataAttr(''foo'')
, y resulta en un tamaño de archivo más pequeño después de la minificación (en comparación con el uso de .attr(''data-foo'')
).