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:

  1. The starting point is that I have multiple ( let's say.. 60 ) different data-attributes and I want to remove all of them.

  2. Preferred way would be to target only those data-attributes that contain the word lorem. In this case lorem is always the first word. (or second if you count data-)

  3. Also I'd like to keep all the other attributes intact

Was it helpful?

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.

https://api.jquery.com/removeData/

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)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top