selectores name examples ejemplos child avanzados jquery jquery-selectors

name - selectores jquery avanzados



selector de datos jquery (9)

Aquí hay un complemento que simplifica la vida https://github.com/rootical/jQueryDataSelector

Úselo así:

data selector jQuery selector $$(''name'') $(''[data-name]'') $$(''name'', 10) $(''[data-name=10]'') $$(''name'', false) $(''[data-name=false]'') $$(''name'', null) $(''[data-name]'') $$(''name'', {}) Syntax error

Necesito seleccionar elementos basados ​​en los valores almacenados en el objeto .data() un elemento. Como mínimo, me gustaría seleccionar propiedades de datos de nivel superior mediante selectores, tal como este:

$(''a'').data("category","music"); $(''a:data(category=music)'');

O tal vez el selector estaría en formato de selector de atributo normal:

$(''a[category=music]'');

O en formato de atributo, pero con un especificador para indicar que está en .data() :

$(''a[:category=music]'');

Descubrí que la implementación de James Padolsey es simple, pero buena. Los formatos de selector de arriba reflejan los métodos mostrados en esa página. También está este parche de Sizzle .

Por alguna razón, recuerdo haber leído hace un tiempo que jQuery 1.4 incluiría soporte para selectores de valores en el objeto jquery .data() . Sin embargo, ahora que lo estoy buscando, no puedo encontrarlo. Quizás fue solo una solicitud de función que vi. ¿Hay apoyo para esto y simplemente no lo estoy viendo?

Idealmente, me gustaría apoyar sub-propiedades en data () usando notación de puntos. Me gusta esto:

$(''a'').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"}); $(''a[:user.name.first=Tom]'');

También me gustaría admitir selectores de datos múltiples, donde solo se encuentran elementos con TODOS los selectores de datos especificados. El selector múltiple jquery normal realiza una operación OR. Por ejemplo, $(''a.big, a.small'') selecciona etiquetas con clase big o small ). Estoy buscando un AND, quizás así:

$(''a'').data("artist",{id: 3281, name: "Madonna"}); $(''a'').data("category","music"); $(''a[:category=music && :artist.name=Madonna]'');

Por último, sería genial si los operadores de comparación y las características de expresiones regulares estuvieran disponibles en los selectores de datos. Entonces $(a[:artist.id>5000]) sería posible. Me doy cuenta de que probablemente podría hacer mucho de esto usando filter() , pero sería bueno tener un formato de selector simple.

¿Qué soluciones hay disponibles para hacer esto? ¿Es la Padolsey de Jame la mejor solución en este momento? Mi preocupación se centra principalmente en el rendimiento, pero también en las características adicionales como la notación de punto de subpropiedad y los selectores de datos múltiples. ¿Hay otras implementaciones que respalden estas cosas o que sean mejores de alguna manera?


Creé un nuevo selector de data que debería permitirle hacer consultas anidadas y condiciones AND. Uso:

$(''a:data(category==music,artist.name==Madonna)'');

El patrón es:

:data( {namespace} [{operator} {check}] )

"operador" y "verificar" son opcionales. Entonces, si solo tienes :data(abc) , simplemente comprobará la veracidad de abc .

Puede ver los operadores disponibles en el siguiente código. Entre ellos está ~= que permite la prueba de expresiones regulares:

$(''a:data(category~=^mus..$,artist.name~=^M.+a$)'');

Lo he probado con algunas variaciones y parece funcionar bastante bien. Probablemente agregue esto como un repositorio de Github pronto (con un conjunto de pruebas completo), así que ¡échale un vistazo!

El código:

(function(){ var matcher = //s*(?:((?:(?:///.|[^.,])+/.?)+)/s*([!~><=]=|[><])/s*("|'')?((?:///3|.)*?)/3|(.+?))/s*(?:,|$)/g; function resolve(element, data) { data = data.match(/(?:///.|[^.])+(?=/.|$)/g); var cur = jQuery.data(element)[data.shift()]; while (cur && data[0]) { cur = cur[data.shift()]; } return cur || undefined; } jQuery.expr['':''].data = function(el, i, match) { matcher.lastIndex = 0; var expr = match[3], m, check, val, allMatch = null, foundMatch = false; while (m = matcher.exec(expr)) { check = m[4]; val = resolve(el, m[1] || m[5]); switch (m[2]) { case ''=='': foundMatch = val == check; break; case ''!='': foundMatch = val != check; break; case ''<='': foundMatch = val <= check; break; case ''>='': foundMatch = val >= check; break; case ''~='': foundMatch = RegExp(check).test(val); break; case ''>'': foundMatch = val > check; break; case ''<'': foundMatch = val < check; break; default: if (m[5]) foundMatch = !!val; } allMatch = allMatch === null ? foundMatch : allMatch && foundMatch; } return allMatch; }; }());


En este momento estoy seleccionando de esta manera:

$(''a[data-attribute=true]'')

Lo cual parece funcionar bien, pero sería bueno si jQuery pudiese seleccionar por ese atributo sin el prefijo ''data-''.

No he probado esto con los datos agregados a los elementos a través de jQuery dinámicamente, por lo que podría ser la caída de este método.


Hay un plugins.jquery.com/project/dataSelector que hace esto :)

Algunos ejemplos basados ​​en su pregunta:

$(''a:data("category=music")'') $(''a:data("user.name.first=Tom")''); $(''a:data("category=music"):data("artist.name=Madonna")''); //jQuery supports multiple of any selector to restrict further, //just chain with no space in-between for this effect

El rendimiento no va a ser muy bueno en comparación con lo que es posible , seleccionar desde $._cache y capturar los elementos correspondientes es, con mucho, el más rápido, pero mucho más redondo y no muy "jQuery-ey" en términos de cómo consigues cosas (por lo general, vienes del lado del elemento). Por encima de todo, no estoy seguro de que este sea el más rápido de todos modos, ya que el proceso de pasar de Id único a elemento es enrevesado en sí mismo, en términos de rendimiento.

El selector de comparación que mencionó será mejor que lo haga en .filter() , no hay soporte integrado para esto en el complemento, aunque podría agregarlo sin muchos problemas.


Puede establecer un atributo data-* en un olmo usando attr() , y luego seleccionar usando ese atributo:

var elm = $(''a'').attr(''data-test'',123); //assign 123 using attr() elm = $("a[data-test=123]"); //select elm using attribute

y ahora para ese olmo, tanto attr() como data() producirán 123 :

console.log(elm.attr(''data-test'')); //123 console.log(elm.data(''test'')); //123

Sin embargo, si modifica el valor para que sea 456 usando attr() , data() seguirá siendo 123 :

elm.attr(''data-test'',456); //modify to 456 elm = $("a[data-test=456]"); //reselect elm using new 456 attribute console.log(elm.attr(''data-test'')); //456 console.log(elm.data(''test'')); //123

Así que, según lo entiendo, parece que probablemente debería evitar attr() comandos attr() y data() en su código si no es necesario. Debido a que attr() parece corresponder directamente con el DOM mientras que data() interactúa con la ''memoria'', aunque su valor inicial puede ser del DOM. Pero el punto clave es que los dos no están necesariamente sincronizados.

Así que ten cuidado

En cualquier caso, si no está cambiando el atributo data-* en el DOM o en la memoria, entonces no tendrá problemas. Cuando comiences a modificar los valores es cuando pueden surgir problemas potenciales.

Gracias a @Clarence Liu a la respuesta de @ Ash, así como a esta publicación .


Quiero advertirle que $(''a[data-attribute=true]'') no funciona, según la respuesta de Ashley, si adjuntó datos a un elemento DOM a través de la función data ().

Funciona como era de esperar si agregaras un attr de datos real en tu HTML, pero jQuery almacena los datos en la memoria, por lo que los resultados que obtendrías de $(''a[data-attribute=true]'') no se correcto

Tendrá que utilizar el complemento de datos http://code.google.com/p/jquerypluginsblog/ , usar la solución de filter de Dmitri, o hacer un $ .each sobre todos los elementos y verificar .data () iterativamente


Si también usas jQueryUI, obtienes una versión (simple) del selector de :data que verifica la presencia de un elemento de datos, para que puedas hacer algo como $("div:data(view)") , o $( this ).closest(":data(view)") .

Ver http://api.jqueryui.com/data-selector/ . No sé cuánto tiempo lo tuvieron, ¡pero está allí ahora!


También puede usar una función de filtrado simple sin complementos. Esto no es exactamente lo que quiere, pero el resultado es el mismo:

$(''a'').data("user", {name: {first:"Tom",last:"Smith"},username: "tomsmith"}); $(''a'').filter(function() { return $(this).data(''user'') && $(this).data(''user'').name.first === "Tom"; });