jQuery - extract class name that 'starts with' prefix [duplicate]
Mia Lopez
My items have the following classes:
<div></div>
<div></div>
<div></div>I'm wondering if there is an easy way to:
- Grab only all classes with
some-class-prefix. - Remove them from each element.
- Have their names (not corresponding DOM elements) in a variable?
I can easily select such elements with jQuery( "div[class^='some-class-'], div[class*=' some-class-']" ) but how its class name could be extracted with the shortest and the most readable code to a variable (can be some global object)?
4 Answers
Like this?
var arrClasses = [];
$("div[class*='some-class-']").removeClass(function () { // Select the element divs which has class that starts with some-class- var className = this.className.match(/some-class-\d+/); //get a match to match the pattern some-class-somenumber and extract that classname if (className) { arrClasses.push(className[0]); //if it is the one then push it to array return className[0]; //return it for removal }
});
console.log(arrClasses);.removeClass() accepts a callback function to do some operation and return the className to be removed, if nothing to be removed return nothing.
2You could loop through all the elements, pull the class name using a regular expression, and store them in an array:
var classNames = [];
$('div[class*="some-class-"]').each(function(i, el){ var name = (el.className.match(/(^|\s)(some\-class\-[^\s]*)/) || [,,''])[2]; if(name){ classNames.push(name); $(el).removeClass(name); }
});
console.log(classNames);<script src=""></script>
<div></div>
<div></div>
<div></div> 2 You can iterate over each found node and iterate over the classes to find a match; if found, remove the class and log it:
var found = [];
$('div[class*="some-class-"]').each(function() { var classes = this.className.split(/\s+/), $this = $(this); $.each(classes, function(i, name) { if (name.indexOf('some-class-') === 0) { $this.removeClass(name); found.push(name); } });
});Note that a selector like div[class*="some-class-"] is pretty expensive and since you need to perform extra processing anyway, it would be easier to just iterate over all div tags and process them:
var elements = document.getElementsByTagName('div'),
found = [];
$.each(elements, function(i, element) { var classes = element.className.split(/\s+/); $.each(classes, function(i, name) { if (name.indexOf('some-class-') === 0) { $(element).removeClass(name); found.push(name); } });
});Modern browsers expose Element.classList which you can use to manipulate class names and Array.forEach for iteration:
var found = [];
[].forEach.call(document.getElementsByTagName('div'), function(element) { (function(names, i) { while (i < names.length) { var name = names[i]; if (name.indexOf('some-class-') === 0) { names.remove(name); found.push(name); } else { ++i; } } }(element.classList, 0));
}); The easy way
You clould create your own filter :
$.fn.hasClassStartsWith = function(className) { return this.filter('[class^=\''+className+'\'], [class*=\''+className+'\']');
}
var divs = $('div').hasClassStartsWith("some-class-");
console.log(divs.get()); 0