¿Cómo encontrar un elemento basado en un valor de atributo de datos?


994

Tengo el siguiente escenario:

var el = 'li';

y hay 5 <li>en la página cada uno con un data-slide=numberatributo (el número es 1,2,3,4,5 respectivamente) .

Ahora necesito encontrar el número de diapositiva activo actualmente que se asigna var current = $('ul').data(current);y se actualiza en cada cambio de diapositiva.

Hasta ahora, mis intentos no han tenido éxito, tratando de construir el selector que coincida con la diapositiva actual:

$('ul').find(el+[data-slide=+current+]);

no coincide / devuelve nada ...

La razón por la que no puedo codificar la liparte es que esta es una variable accesible para el usuario que se puede cambiar a un elemento diferente si es necesario, por lo que puede no ser siempre una li.

¿Alguna idea de lo que me falta?


66
¿Estás seguro de que dentro de ti .find(el+[data-slide=+current+]);está el código que escribes? parece que te perdiste algunas citas para"[data-slide]"
xandy

Eso es lo que me ayudó a seleccionar todos los atributos de datos (independientemente del valor): $('*[data-slide]')puede usarlo con, por ejemplo$('*[data-slide]').each( function() { ... });
Kai Noack el

Respuestas:


1481

Debe inyectar el valor de currenten un selector de Atributo igual :

$("ul").find(`[data-slide='${current}']`)

Para entornos JavaScript más antiguos ( ES5 y anteriores):

$("ul").find("[data-slide='" + current + "']"); 

8
@ Jannis, podrías hacerlo $("ul").find(el + "[data-slide='" + current +"']");.
Frédéric Hamidi

77
@ c00lryguy, jQuery UI define uno, y existen implementaciones independientes . Parece que los intentos de agregarlo a jQuery Core fueron rechazados . Dos veces .
Frédéric Hamidi

66
esta respuesta en una publicación similar tiene un ejemplo de la función de filtro
drzaus

77
Me preocupa que esto no funcione si los datos se agregaron a través de la función jQuery .data (...), ya que esto no siempre representa un atributo y algunas veces utiliza un mecanismo de almacenamiento específico del navegador. Otra razón por la que desearía que jQuery core tuviera un selector de datos específicos.
AaronLS

77
Observe que no funciona para los elementos donde establece datos con $ ('# elemento'). Data ('some-att-name', value); pero solo para aquellos con atributos codificados. Tengo este problema y para que funcione, establezca los datos escribiendo el atributo directamente $ ('# element'). Attr ('data-some-att-name', value);
Pawel

463

en caso de que no desee escribir todo eso, aquí hay una forma más corta de consultar por atributo de datos:

$("ul[data-slide='" + current +"']");

FYI: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/


31
Para aquellos de ustedes a quienes les importa, dada la estructura, <ul><li data-slide="item"></li></ul>el selector de esta respuesta volverá indefinido, por lo que no funciona dado el escenario del usuario. Esta respuesta FUNCIONARÁ para la estructura <ul data-slide="item"><li></li></ul> Si bien entiendo por qué su popularidad debido a la brevedad, técnicamente es una respuesta incorrecta. jsfiddle.net/py5p2abL/1
akousmata

44
No olvides tratarlo como una matriz. Use [0]para acceder al primer elemento encontrado.
Aminah Nuraini

Un extraño efecto secundario ... este método funcionó haciendo coincidir el elemento con el atributo de datos cuando .find("[data-attrib='value']")no funcionó. No sé si los valores eran atributos de datos agregados por jQuery o no ...
error

1
No es extraño porque las dos respuestas hacen 2 cosas diferentes. encuentra$.find específicamente los descendientes de ese elemento, pero el uso de la sintaxis de filtro en la cadena de selección simplemente filtrará los resultados.
Phil

227

Cuando busque con [data-x = ...], tenga cuidado, no funciona con jQuery.data (..) setter :

$('<b data-x="1">'  ).is('[data-x=1]') // this works
> true

$('<b>').data('x', 1).is('[data-x=1]') // this doesn't
> false

$('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
> true

Puedes usar esto en su lugar:

$.fn.filterByData = function(prop, val) {
    return this.filter(
        function() { return $(this).data(prop)==val; }
    );
}

$('<b>').data('x', 1).filterByData('x', 1).length
> 1

1
el $.fn.filterByDataes brillante; sin embargo, esta es una advertencia para los copy-pasters ... solo necesita $('<b>').filterByData('x', 1)encontrar <b>etiquetas con data-x="1". si copia y pega la .data(x, 1)parte ... configurará su data-x"1" antes de filtrar.
WEBjuju

39

Creo que he mejorado en filterByData extensión de BRM psico a jQuery.

Cuando la extensión anterior buscó en un par clave-valor, con esta extensión también puede buscar la presencia de un atributo de datos, independientemente de su valor.

(function ($) {

    $.fn.filterByData = function (prop, val) {
        var $self = this;
        if (typeof val === 'undefined') {
            return $self.filter(
                function () { return typeof $(this).data(prop) !== 'undefined'; }
            );
        }
        return $self.filter(
            function () { return $(this).data(prop) == val; }
        );
    };

})(window.jQuery);

Uso:

$('<b>').data('x', 1).filterByData('x', 1).length    // output: 1
$('<b>').data('x', 1).filterByData('x').length       // output: 1

O el violín: http://jsfiddle.net/PTqmE/46/


34

Sin JQuery, ES6

document.querySelectorAll(`[data-slide='${current}']`);

Sé que la pregunta es sobre JQuery, pero los lectores pueden querer un método JS puro.


33

Me he enfrentado al mismo problema al buscar elementos usando jQuery y el atributo data- *.

así que para su referencia, el código más corto está aquí:

Este es mi código HTML:

<section data-js="carousel"></section>
<section></section>
<section></section>
<section data-js="carousel"></section>

Este es mi selector jQuery:

$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.


15

Este selector $("ul [data-slide='" + current +"']");funcionará para la siguiente estructura:

<ul><li data-slide="item"></li></ul>  

Si bien esto $("ul[data-slide='" + current +"']");funcionará para:

<ul data-slide="item"><li></li></ul>


12

Volviendo a su pregunta original, sobre cómo hacer que esto funcione sin conocer de antemano el tipo de elemento, lo siguiente hace esto:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.