Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
490 views
in Technique[技术] by (71.8m points)

jquery - How to get, set and select elements with data attributes?

I'm having some trouble with data-attributes, I can't get anything to work for some reason so I must be doing something wrong:

Set:

$('#element').data('data1', '1'); //Actually in my case the data is been added manually 

Does that make a difference?

Get:

$('#element').data('data1');

Select:

$('#element[data1 = 1]')

None of this works for me, am I making this up or how is it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

All of the answers are correct, but I want to state something that nobody else did.
The jQuery data method acts like a getter for html5 data attributes, but the setter does not alter the data-* attribute.
So, If you manually added the data (as is stated in your comment), then you can use a css attribute selector to select your element :

$('#element[data-data1=1]')  

but if you have added (altered) the data via jQuery, then the above solution won't work.
Here's an example of this failure :

var div = $('<div />').data('key','value');
alert(div.data('key') == div.attr('data-key'));// it will be false  

So the workaround is to filter the collection by checking the jQuery data value to match the desired one :

// replace key & value with own strings
$('selector').filter(function(i, el){
    return $(this).data('key') == 'value';
});

So, in order to overcome these issues, you need to use the html5 dataset attributes (via jQuery's attr methos) as getters and setters :

$('selector').attr('data-' + key, value);

or you can use a custom expression that filters jQuery internal data :

$.expr[':'].data = function(elem, index, m) {
    // Remove ":data(" and the trailing ")" from the match, as these parts aren't needed:
    m[0] = m[0].replace(/:data(|)$/g, '');
    var regex = new RegExp('(['"]?)((?:\\\1|.)+?)\1(,|$)', 'g'),
    // Retrieve data key:
    key = regex.exec( m[0] )[2],
    // Retrieve data value to test against:
    val = regex.exec( m[0] );
    if (val) {
        val = val[2];
    }
    // If a value was passed then we test for it, otherwise we test that the value evaluates to true:
    return val ? $(elem).data(key) == val : !!$(elem).data(key);
};

and use it like :

$('selector:data(key,value)')

Update

I know this thread is a few years old, but since it has some activity, it's worth mentioning that doing this using the querySelector dom API (with no need for jQuery) is quite trivial:

document.querySelectorAll('[attribute=value]')

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...