50

Is it possible to remove all attributes at once using jQuery?

<img src="example.jpg" width="100" height="100">

to

<img>

I tried $('img').removeAttr('*'); with no luck. Anyone?

cletus
  • 616,129
  • 168
  • 910
  • 942
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • Bad idea, you should only remove what attributes you know about, a DOM element has a lot more attributes than what you specify in the tag each with their own default or calculated value. – row1 Dec 09 '09 at 03:03
  • I tried to use user993683 answer in Vue. It worked, but afterward my styles were acting weird. I checked the attributes and there was one named data-v. Turns out Vue uses this to apply scoped styles. It didn't take me long to find the problem, but I would be carful when using one of these solutions. Especially, when using frameworks. – dev7 May 13 '21 at 10:18

10 Answers10

81

A simple method that doesn't require JQuery:

while(elem.attributes.length > 0)
    elem.removeAttribute(elem.attributes[0].name);
  • 2
    Be careful if you selected a JQuery object. You need to convert it to htmlElement ([$elem.get(0)](https://api.jquery.com/get/)) before using this method. – Gabriel GM Jul 14 '16 at 14:21
  • 1
    I'm not sure why all examples contain something like "elem.attributes.length" In my opinion a bit faster is something like: while (elem.attributes[0]) { elem.attributes.removeNamedItem(elem.attributes[0].name); } – portal TheAnGeLs Feb 05 '23 at 13:12
52

Update: the previous method works in IE8 but not in IE8 compatibility mode and previous versions of IE. So here is a version that does and uses jQuery to remove the attributes as it does a better job of it:

$("img").each(function() {
  // first copy the attributes to remove
  // if we don't do this it causes problems
  // iterating over the array we're removing
  // elements from
  var attributes = $.map(this.attributes, function(item) {
    return item.name;
  });

  // now use jQuery to remove the attributes
  var img = $(this);
  $.each(attributes, function(i, item) {
    img.removeAttr(item);
  });
});

Of course you could make a plug-in out of it:

jQuery.fn.removeAttributes = function() {
  return this.each(function() {
    var attributes = $.map(this.attributes, function(item) {
      return item.name;
    });
    var img = $(this);
    $.each(attributes, function(i, item) {
    img.removeAttr(item);
    });
  });
}

and then do:

$("img").removeAttributes();
cletus
  • 616,129
  • 168
  • 910
  • 942
  • No need for a plugin, it was the while loop I was after. Thanks! – David Hellsing Dec 08 '09 at 23:19
  • Err, no. This doesn't come close to a working solution for IE. `removeAttribute` does not work at all like you expect here (hint: that `while` loop is gonna lock up the poor browser forever). – Crescent Fresh Dec 09 '09 at 02:37
  • 1
    just came across this - I wish u could lock up IE forever across all computers at once, and only allow one tab to work, which points to the Chrome download page. That would be awesome! (and no, I don't mean allow IE 9 or 10 - IE 6 was / **still is** so rubbish that IE 9 and 10 deserve to suffer!) – ClarkeyBoy Feb 11 '13 at 19:03
  • By the way this came in very very useful today - just taken this as the basis for my plugin and passed options into the function (with defaults using `$.extend`) so that I can say I want to remove all attributes from these elements, besides these attributes (name, id, class etc. go here). Attributes are accepted as an object, array or string (which is split on comma). – ClarkeyBoy Feb 11 '13 at 19:08
  • 1
    What for you run 2 loops (map and each)? It's performance inefficient when it's required to remove attributes from a mass of elements. You can easily combine these into a single loop: `$.each(this.attributes, function(i, item) { img.removeAttr(item.name) });` – Nik Sumeiko Feb 22 '15 at 19:24
  • @manakor the reason why 1 loop wont work is because removeAttr alters this.attributes, thereby breaking the iteration and finding "item" is undefined. I just tried it. – ZeroGravityChimp Feb 27 '15 at 02:12
  • 1
    @ZeroGravityChimp start looping from the end of attributes array to avoid skipping elements due to the changing length: `for (var i = this.attributes.length -1; i >= 0 ; i--) { img.removeAttr(this.attributes[i].name); }` – Nik Sumeiko Feb 27 '15 at 06:49
  • @manakor +1 for altering your code to make it work. Personally, though, I wouldn't use this because its simpler and easier to maintain 2 separated for loops with exact purposes. eg if you decide later to comment that line out your application will enter an infinite loop. Loops that change what they are looping over are dangerous in my opinion. – ZeroGravityChimp Mar 01 '15 at 23:51
  • @manakor Woops sorry not infinite loop. That part of my comment is totally wrong. Just suggesting that to avoid errors its better to pull out the iteration list specifically instead of alter the collection as you go. – ZeroGravityChimp Mar 02 '15 at 00:01
18

One-liner, no jQuery needed:

[...elem.attributes].forEach(attr => elem.removeAttribute(attr.name));
5

Instead of creating a new jQuery.fn.removeAttributes (demonstrated in the accepted answer) you can extend jQuery's existing .removeAttr() method making it accept zero parameters to remove all attributes from each element in a set:

var removeAttr = jQuery.fn.removeAttr;
jQuery.fn.removeAttr = function() {

  if (!arguments.length) {
    this.each(function() {

      // Looping attributes array in reverse direction
      // to avoid skipping items due to the changing length
      // when removing them on every iteration.
      for (var i = this.attributes.length -1; i >= 0 ; i--) {
        jQuery(this).removeAttr(this.attributes[i].name);
      }
    });

    return this;
  }

  return removeAttr.apply(this, arguments);
};

Now you can call .removeAttr() without parameters to remove all attributes from the element:

$('img').removeAttr();
Nik Sumeiko
  • 8,263
  • 8
  • 50
  • 53
1

One-liner.

For jQuery users

$('img').removeAttr(Object.values($('img').get(0).attributes).map(attr => attr.name).join(' '));
steven7mwesigwa
  • 5,701
  • 3
  • 20
  • 34
1

One don't need to refer to the name of attribute to to id nowadays, since we have removeAttributeNode method.

while(elem.attributes.length > 0) {
    elem.removeAttributeNode(elem.attributes[0]);
}

shabunc
  • 23,119
  • 19
  • 77
  • 102
1

One very good reason to do this for specific tags is to clean up legacy content and also enforce standards.

Let's say, for example, you wanted to remove legacy attributes, or limit damage caused by FONT tag attributes by stripping them.

I've tried several methods to achieve this and none, including the example above, work as desired.

Example 1: Replace all FONT tags with the contained textual content. This would be the perfect solution but as of v1.6.2 has ceased to function. :(

$('#content font').each(function(i) {
   $(this).replaceWith($(this).text());
});

Example 2: Strip all attributes from a named tag - e.g. FONT. Again, this fails to function but am sure it used to work once upon a previous jQuery version.

$("font").each(function() {
 // First copy the attributes to remove.
 var attributes = $.map(this.attributes, function(item) {
   return item.name;
 });     
 // Now remove the attributes
 var font = $(this);
 $.each(attributes, function(i, item) {
   $("font").removeAttr(item);
 });
});

Looking forward to 1.7 which promises to include a method to remove multiple attributes by name.

Panoone
  • 11
  • 1
0

This will remove all attributes and it will work for every type of element.

    var x = document.createElement($("#some_id").prop("tagName"));
    $(x).insertAfter($("#some_id"));
    $("#some_id").remove();
Ahmet Can Güven
  • 5,392
  • 4
  • 38
  • 59
0

I don't know exactly what you're using it for, but have you considered using css classes instead and toggling those ? It'll be less coding on your side and less work for the browser to do. This will probably not work [easily] if you're generating some of the attributes on the fly like with and height.

sjobe
  • 2,817
  • 3
  • 24
  • 32
-1

Today I have same issue. I think that it will be useful for you

var clone = $(node).html();
clone = $('<tr>'+ clone +'</tr>');
clone.addClass('tmcRow');