You actually have two problems with your code, each of which is partially masking the other.
"test
called multiple times on the same global regular expression instance will advance past the previous match." As a result, every other time you performed .test
using the same regex, it wasn't searching from the beginning of the string. I replaced regex.test(str)
with str.search(regex)>=0
to solve this problem.
In addition, your script seemed to have indexing problems because you were removing attributes in the middle of the loop. I believe this is because "Arrays and array-like objects with a length property...are iterated by numeric index, from 0 to length-1." Removing the attributes all at once after the loop solved the problem (.removeAttr()
will accept a space-separated list of attributes to remove.)
$.fn.removeAttrs = function(regex) {
var regex = new RegExp(regex, "g");
return this.each(function() {
var _this = $(this);
var removethese = '';
$.each(this.attributes, function(i, attrib){
if (attrib && attrib.specified && attrib.name.search(regex)>=0) {
removethese += ' '+attrib.name;
}
});
_this.removeAttr(removethese);
});
};
http://jsfiddle.net/mblase75/YHyjC/
Note that using .removeAttr()
in this way is effectively repeating the loop a second time, so for maximum efficiency, you should retool your code and use a for
loop that counts backwards through this.attributes
and removes them at the same time. However, for a single short set of attributes, the performance gain will be minimal.
$.fn.removeAttrs = function(regex) {
var regex = new RegExp(regex, "g");
return this.each(function() {
var _this = $(this);
for (var i=this.attributes.length-1; i>=0; i--){
var attrib = this.attributes[i];
if (attrib && attrib.specified && attrib.name.search(regex)>=0) {
_this.removeAttr(attrib.name);
}
}; // end for
});
};
http://jsfiddle.net/mblase75/Zm4qR/