How to get, set and select elements with data attr

2019-01-22 12:24发布

问题:

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?

回答1:

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)')


回答2:

To reflect the values of the Attributes immediately in the DOM you can use .attr()

$('#element').attr('data-data1', '1');  // Sets the attribute

$('#element[data-data1="1"]') // Selects the element with data-data1 attribute'

$('#element').data('data1'); // Gets the value  of the attribute

$('#element').attr('data-data1'); // Gets the value  of the attribute

In plain Javascript you can try this

var elem = document.getElementById('element');

elem.setAttribute('data-data1', '1'); // Set the attribute

elem.getAttribute('data-data1'); // Gets the attribute


回答3:

// Set
$('#element').attr('data-value', 'value');
// Get
var value = $('#element').attr('data-value');
// Select
var elem = $('#element[data-value = "' +value+ '"]');


回答4:

You are using ID selector so there is no need to use attribute selector, as data is a property and you are setting it using data method (not attr method) you cannot select the element using attribute selector, if you want to select the element only if it has data1 === 1 you can use the filter method:

(function($){
    $(function(){
       // ...
       $('#element').filter(function() {
          return this.dataset.data1 == 1
          // return $(this).data('data1') == 1
       })
    })
})(jQuery);

dataset: Allows access, both in reading and writing mode, to all the custom data attributes (data-*) set on the element. It is a map of DOMString, one entry for each custom data attribute.