jQuery treats data-attributes in an interesting way, wherein it retrieves values once and does not observe changes or removals after that point. Modification of the data is achieved by using jQuery's various functions – $element.data('key', 'val') etc. As such, it muddies the code to do things like $element.prop('data-key', 'val') and $element.removeProp('data-key', 'val') because this does not touch the jQuery Data API, even though it would reasonably appear that these calls are intended to do that.
However, that means of altering the DOM seems to be the only way to successfully use data-attributes for delegated event listeners "the jQuery way:"
$element.on('click', '[data-key=val]', function(e) {
// only triggers on children of $element that have the DOM attribute
// data-attribute data-key, with a value of val
});
Data-attributes don't clog up classnames etc and seem like a reasonable place to put certain element attributes for JavaScript usage. But now if I write $element.find('div').data('key', 'val'), these elements will not meet the criteria when clicked. The only way to accomplish that is by saying $element.find('div').prop('data-key', 'val'), which is not a best practice as I understand it.
The other option is this:
$element.on('click', 'div', function(e) {
if ($(this).data('key') != 'val') return;
// handle
});
This seems clunky, and will trigger more frequently than the above. It's also a little less clear what we're actually targeting.
Were it not delegated, I could write:
$element.find('div')
.filter(function() { return $(this).data('key') == 'val'; })
.on('click', function(e) {
// handle
});
But .filter() won't work for delegated listeners, which only accept a string selector.
So the problem is this: I have multiple solutions already, but none are ideal, and none really follow jQuery's idiom. How can I assign delegated listeners based on the jQuery Data API?
Try utilizing
HTMLElement.datasetjsfiddle http://jsfiddle.net/a7qcafwf/1/