¿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.