简体   繁体   中英

jQuery how to find an element based on a data-attribute value?

I've got the following scenario:

var el = 'li';

and there are 5 <li> 's on the page each with a data-slide=number attribute (number being 1,2,3,4,5 respectively) .

I now need to find the currently active slide number which is mapped to var current = $('ul').data(current); and is updated on each slide change.

So far my tries have been unsuccessful, trying to construct the selector that would match the current slide:

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

does not match/return anything…

The reason I can't hardcode the li part is that this is a user accessible variable that can be changed to a different element if required, so it may not always be an li .

Any ideas on what I'm missing?

You have to inject the value of current into an Attribute Equals selector:

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

For older JavaScript environments ( ES5 and earlier):

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

in case you don't want to type all that, here's a shorter way to query by data attribute:

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

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

When searching with [data-x=...], watch out, it doesn't work with 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

You can use this instead:

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

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

Without JQuery, ES6

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

I know the question is about JQuery, but readers may want a pure JS method.

I improved upon psycho brm's filterByData extension to jQuery.

Where the former extension searched on a key-value pair, with this extension you can additionally search for the presence of a data attribute, irrespective of its value.

(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);

Usage:

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

 // test data function extractData() { log('data-prop=val ...... ' + $('div').filterByData('prop', 'val').length); log('data-prop .......... ' + $('div').filterByData('prop').length); log('data-random ........ ' + $('div').filterByData('random').length); log('data-test .......... ' + $('div').filterByData('test').length); log('data-test=anyval ... ' + $('div').filterByData('test', 'anyval').length); } $(document).ready(function() { $('#b5').data('test', 'anyval'); }); // the actual extension (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); //just to quickly log function log(txt) { if (window.console && console.log) { console.log(txt); //} else { // alert('You need a console to check the results'); } $("#result").append(txt + "<br />"); }
 #bPratik { font-family: monospace; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div id="bPratik"> <h2>Setup</h2> <div id="b1" data-prop="val">Data added inline :: data-prop="val"</div> <div id="b2" data-prop="val">Data added inline :: data-prop="val"</div> <div id="b3" data-prop="diffval">Data added inline :: data-prop="diffval"</div> <div id="b4" data-test="val">Data added inline :: data-test="val"</div> <div id="b5">Data will be added via jQuery</div> <h2>Output</h2> <div id="result"></div> <hr /> <button onclick="extractData()">Reveal</button> </div>

Or the fiddle: http://jsfiddle.net/PTqmE/46/

I have faced the same issue while fetching elements using jQuery and data-* attribute.

so for your reference the shortest code is here:

This is my HTML Code:

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

This is my jQuery selector:

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

This selector $("ul [data-slide='" + current +"']"); will work for following structure:

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

While this $("ul[data-slide='" + current +"']"); will work for:

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

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

I hope this may work better

thanks

回到他最初的问题,关于如何在事先不知道元素类型的情况下进行这项工作,以下是这样做的:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM