Remove multiple html5 data-attributes with jquery
-
12-11-2019 - |
Question
So jquery api says the following:
Removing data from jQuery's internal .data() cache does not effect any HTML5 data- attributes in a document; use .removeAttr() to remove those.
I have no problem removing a single data-attribute.
<a title="title" data-loremIpsum="Ipsum" data-loremDolor="Dolor"></a>
$('a').removeAttr('data-loremipsum');
The question is, how can I remove multiple data-attributes?
More details:
The starting point is that I have multiple ( let's say.. 60 ) different data-attributes and I want to remove all of them.
Preferred way would be to target only those data-attributes that contain the word
lorem
. In this caselorem
is always the first word. (or second if you countdata-
)Also I'd like to keep all the other attributes intact
Solution
// Fetch an array of all the data
var data = $("a").data(),
i;
// Fetch all the key-names
var keys = $.map(data , function(value, key) { return key; });
// Loop through the keys, remove the attribute if the key contains "lorem".
for(i = 0; i < keys.length; i++) {
if (keys[i].indexOf('lorem') != -1) {
$("a").removeAttr("data-" + keys[i]);
}
}
Fiddle here: http://jsfiddle.net/Gpqh5/
OTHER TIPS
In my jQuery placeholder plugin, I’m using the following to get all the attributes for a given element:
function args(elem) {
// Return an object of element attributes
var newAttrs = {},
rinlinejQuery = /^jQuery\d+$/;
$.each(elem.attributes, function(i, attr) {
if (attr.specified && !rinlinejQuery.test(attr.name)) {
newAttrs[attr.name] = attr.value;
}
});
return newAttrs;
}
Note that elem
is an element object, not a jQuery object.
You could easily tweak this, to get only data-*
attribute names:
function getDataAttributeNames(elem) {
var names = [],
rDataAttr = /^data-/;
$.each(elem.attributes, function(i, attr) {
if (attr.specified && rDataAttr.test(attr.name)) {
names.push(attr.name);
}
});
return names;
}
You could then loop over the resulting array, and call removeAttr()
for each item on the element.
Here’s a simple jQuery plugin that should do the trick:
$.fn.removeAttrs = function(regex) {
return this.each(function() {
var $this = $(this),
names = [];
$.each(this.attributes, function(i, attr) {
if (attr.specified && regex.test(attr.name)) {
$this.removeAttr(attr.name);
}
});
});
};
// remove all data-* attributes
$('#my-element').removeAttrs(/^data-/);
// remove all data-lorem* attributes
$('#my-element').removeAttrs(/^data-lorem/);
Vanilla JS below clears all data attributes. If you want to add some if
logic to remove a subset of data attributes, it should be trivial to add that functionality to the below JavaScript.
function clearDataAttributes(el){
if (el.hasAttributes()) {
var attrs = el.attributes;
var thisAttributeString = "";
for(var i = attrs.length - 1; i >= 0; i--) {
thisAttributeString = attrs[i].name + "-" + attrs[i].value;
el.removeAttribute(thisAttributeString);
}
}
}
I'll post answer as well, as it took me some time to make working version from Mathias post.
The problems I had was that SVG needs extra-care, there are little nuances(jQuery doesn't like it), but here is the code that should work for SVG as well:
$.fn.removeAttrs = function(attrToRemove, attrValue) {
return this.each(function() {
var $this = $(this)[0];
var toBeRemoved = [];
_.each($this.attributes, function (attr) {
if (attr && attr.name.indexOf(attrToRemove) >= 0) {
if (attrValue && attr.value !== attrValue)
return;
toBeRemoved.push(attr.name);
}
});
_.each(toBeRemoved, function(attrName) {
$this.removeAttribute(attrName);
});
});
};
note that it is using underscore, but you could replace _.each with $.each I believe.
Usage:
svgMapClone
.find('*')
.addBack()
.removeAttrs('svg-')
.removeAttrs('context-')
.removeAttrs('class', '')
.removeAttrs('data-target')
.removeAttrs('dynamic-cursor')
.removeAttrs('transform', 'matrix(1, 0, 0, 1, 0, 0)')
.removeAttrs("ng-");
You can loop all of the data attributes of specific element and filter for index of a sub-string.
REMOVE_ATTR I used the .removeAttr() method, but you may be able to use the .removeData() method depending on how the data-attribute was created. Substitute or combine as you see fit.
$.each($('div').data(), function (i) {
var dataName = i, criteria = "lorem";
if (dataName.indexOf(criteria) >= 0) {
$('div').removeAttr("data-"+dataName);
}
});
SET NULL You can also optionally set the data-attribute to null depending on your business logic.
$.each($('div').data(), function (i) {
var dataName = i, criteria = "lorem";
if (dataName.indexOf(criteria) >= 0) {
$('div').data(dataName, "");
}
});
use the jQuery method removeData()
jQuery site states:
The .removeData() method allows us to remove values that were previously set using .data(). When called with the name of a key, .removeData() deletes that particular value. When called with no arguments, .removeData() removes all values.
The key part here is:
When called with no arguments, .removeData() removes all values.
Sadly it is not possible in jQuery to select attribute names that starts with a given value (for attribute values it is possible).
The easiest solution i came up with:
$(document).ready(function(){
$('[data-loremIpsum], [data-loremDolor]').each(function(index, value) {
$(this).removeAttr('data-loremIpsum')
.removeAttr('data-loremDolor');
});
});
JsFiddle Demo (Make sure to look up the html source code after you clicked run)