Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - extract class name that 'starts with' prefix [duplicate]

My items have the following classes:

<div class="class-x some-class-1 other-class"></div>
<div class="some-class-45 class-y"></div>
<div class="some-class-123 something-else"></div>

I'm wondering if there is an easy way to:

  1. Grab only all classes with some-class- prefix.
  2. Remove them from each element.
  3. 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)?

like image 812
Atadj Avatar asked Jun 28 '13 14:06

Atadj


3 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);

Fiddle

.removeClass() accepts a callback function to do some operation and return the className to be removed, if nothing to be removed return nothing.

like image 133
PSL Avatar answered Oct 18 '22 17:10

PSL


You 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="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="class-x some-class-1 other-class"></div>
<div class="some-class-45 class-y"></div>
<div class="some-class-123 something-else"></div>
like image 4
nderscore Avatar answered Oct 18 '22 16:10

nderscore


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));
});
like image 3
Ja͢ck Avatar answered Oct 18 '22 16:10

Ja͢ck