Necesito seleccionar elementos basados en valores almacenados en el .data()
objeto de un elemento . Como mínimo, me gustaría seleccionar propiedades de datos de nivel superior utilizando selectores, tal vez así:
$('a').data("category","music");
$('a:data(category=music)');
O tal vez el selector estaría en formato de selector de atributo regular:
$('a[category=music]');
O en formato de atributo, pero con un especificador para indicar que está en .data()
:
$('a[:category=music]');
He encontrado que la implementación de James Padolsey parece simple, pero buena. Los formatos del selector sobre los métodos espejo que se muestran en esa página. También existe este parche 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 .data()
objeto jquery . Sin embargo, ahora que lo estoy buscando, no puedo encontrarlo. Tal vez fue solo una solicitud de función que vi. ¿Hay soporte para esto y simplemente no lo estoy viendo?
Idealmente, me gustaría admitir subpropiedades 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 múltiples selectores de datos, donde solo se encuentran elementos con TODOS los selectores de datos especificados. El selector múltiple jquery regular realiza una operación OR. Por ejemplo, $('a.big, a.small')
selecciona a
etiquetas con clase big
o small
). Estoy buscando un AND, tal vez 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 funciones 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 mejor solución de Jame's Padolsey 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 puntos de subpropiedad y los selectores de datos múltiples. ¿Hay otras implementaciones que admitan estas cosas o que sean mejores de alguna manera?
fuente
Respuestas:
He creado un nuevo
data
selector que debería permitirle realizar consultas anidadas y condiciones AND. Uso:El patrón es:
"operador" y "cheque" son opcionales. Entonces, si solo lo tiene
:data(a.b.c)
, simplemente verificará la veracidad dea.b.c
.Puede ver los operadores disponibles en el siguiente código. Entre ellos está el
~=
que permite la prueba de expresiones regulares:Lo he probado con algunas variaciones y parece funcionar bastante bien. Probablemente agregaré esto como un repositorio de Github pronto (con un conjunto de pruebas completo), ¡así que esté atento!
El código:
fuente
$("a:data(condition),a:data(orCondition)")
... tendrá el mismo efecto. Cuantas más funciones agregue, más lento será. Si la lógica es compleja, úsela$(foo).filter(function(){...})
.jQuery.data
, que no obtiene los datos definidos en los atributos HTML5. Si desea esa funcionalidad, puede cambiarjQuery.data
a$('selector').data
, pero eso es una compensación por la velocidad.En este momento estoy seleccionando así:
Lo que parece funcionar bien, pero sería bueno si jQuery pudiera seleccionar por ese atributo sin el prefijo 'data-'.
No he probado esto con datos agregados a elementos a través de jQuery dinámicamente, por lo que podría ser la caída de este método.
fuente
También puede usar una función de filtrado simple sin complementos. Esto no es exactamente lo que quieres, pero el resultado es el mismo:
fuente
filter
función transversal podría aceptar una función de prueba =) graciasQuiero 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 es de esperar si agrega un atributo de datos real en su HTML, pero jQuery almacena los datos en la memoria, por lo que los resultados que obtendría
$('a[data-attribute=true]')
no serían correctos.Deberá usar el complemento de datos http://code.google.com/p/jquerypluginsblog/ , usar la
filter
solución de Dmitri o hacer un $ .each sobre todos los elementos y verificar .data () iterativamentefuente
Hay un
:data()
complemento de filtro que hace exactamente esto :)Algunos ejemplos basados en su pregunta:
El rendimiento no va a ser extremadamente bueno en comparación con lo que es posible , seleccionar
$._cache
y tomar 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 llegar a cosas (generalmente vienes desde el lado del elemento). De todos modos, no estoy seguro de que esto sea más rápido de todos modos ya que el proceso de pasar de un Id único a un elemento es complicado en sí mismo, en términos de rendimiento.El selector de comparación que mencionó será mejor en un
.filter()
, no hay soporte incorporado para esto en el complemento, aunque puede agregarlo sin muchos problemas.fuente
data-*
atributos HTML5 y seleccionarlos sería más rápido que seleccionar.data()
propiedades? Además, ¿alguna idea de dónde puedo encontrar más información sobre $ ._ caché? Busqué en Google, pero no encuentro mucho.$.cache
así$._cache
, puedes ver cómo se implementa y usa en jQuery core aquí: github.com/jquery/jquery/blob/master/src/data.js#L4 Cuando llamas.data()
, en realidad lo almacena como un objeto in$.cache[elementUniqueID]
, que es un Id asignado según sea necesario de manera incriminatoria a cada elemento, por ejemplo, 1, 2, 3, etc. Ese ID de escalada se expondrá en jQuery 1.4.3, creo, basado en los comentarios git del otro día. Supongo que la ruta HTML 5 sería más rápida, depende de las optimizaciones del navegador que estén disponibles (estoy seguro de que habrá más disponibles).Puede establecer un
data-*
atributo en un olmo usandoattr()
, y luego seleccionar usando ese atributo:y ahora para ese olmo, ambos
attr()
ydata()
producirán 123 :Sin embargo, si se modifica el valor de ser 456 utilizando
attr()
,data()
todavía será 123 :Entonces, según tengo entendido, parece que probablemente debería evitar la mezcla
attr()
y losdata()
comandos en su código si no es necesario. Porqueattr()
parece corresponder directamente con el DOM, mientras quedata()
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 en absoluto.Así que ten cuidado.
En cualquier caso, si no está cambiando el
data-*
atributo en el DOM o en la memoria, no tendrá ningún problema. Tan pronto como comience 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 .
fuente
Funciona. Ver Atributo Selector de igual [nombre = ”valor”] .
fuente
Si también usa jQueryUI, obtiene una versión (simple) del
:data
selector que verifica la presencia de un elemento de datos, por lo que puede hacer algo como$("div:data(view)")
, o$( this ).closest(":data(view)")
.Ver http://api.jqueryui.com/data-selector/ . No sé por cuánto tiempo lo han tenido, ¡pero está allí ahora!
fuente
Aquí hay un complemento que simplifica la vida https://github.com/rootical/jQueryDataSelector
Úselo así:
fuente