-1

There is a javascript string that is a valid html code. What's the fastest way to get a javascript array that contains all classes grabbed from that string?

var mystr = '<div class="class1 class2"><p id="id1">some <span class="class3">text about class="class4"</span></p></div>';

The expected result is

var myarr =  ["class1","class2","class3"];

Please unique classes only. The order in this array is not a matter.

Huangism
  • 16,278
  • 7
  • 48
  • 74
Haradzieniec
  • 9,086
  • 31
  • 117
  • 212
  • That's going to be more of a hassle than you may think. Any way, that string is not a valid JS string. You're going to have to either escape the inner quotes, or use single quotes for the string itself. – Cerbrus Oct 01 '14 at 14:06
  • @Cerbus. Sorry, changed some " to '. – Haradzieniec Oct 01 '14 at 14:07

3 Answers3

3

One approach, avoiding regular expressions:

// create a <div>' to hold the HTML:
var div = document.createElement('div');
// set the innerHTML of the <div> to the string of HTML:
div.innerHTML = '<div class="class1 class2"><p id="id1">some <span class="class3">text about class="class4"</span></p></div>';
// get all elements within the <div> that have a class attribute:
classed = div.querySelectorAll('[class]'),
// create an empty array to hold the found class-names:
  classes = [];

// iterate over the elements with a class-attribute, using forEach:
[].forEach.call(classed, function(el) {
  // iterate over the classes that the current element has, using 'classList':
  [].forEach.call(el.classList, function(c) {
    // if the current class (from the classList) isn't already in the array,
    // we add it to the array:
    if (classes.indexOf(c) === -1) {
      classes.push(c);
    }
  });
});

console.log(classes);

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
2

You can do it like this:

var div = document.createElement('div'), //Create a "container" for the html
    elements, classes = [];
// Insert the HTML into the container, allowing the browser to parse it's DOM
div.innerHTML = '<div class="class1 class2"><p id="id1">some <span class="class3">text about class="class4"</span></p></div>'  then.
var elements = div.querySelectorAll('*'); // Get an array of all elements

for(var i = 0; i < elements.length; i++){
    classes = classes.concat(elements[i].className.split(' ')) // Concat an array of classnames for each element in there.
}

classes = classes.filter(function(element){return element !== ''}) // Filter out empty class names.

console.log(classes)
alert(JSON.stringify(classes))

Please note that this uses both:
forEach And querySelectorAll, which are both only fully supported from IE 9 up.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
1

These above methods just seem too complex for this problem. I don't think you have to append the string to the document. I would simply just separate the string by the substring 'class="' and do work from there.

var tags = mystr.split("class=\"");
var classes = new Array();
var endclass;
for (var i=0; i<tags.length; i++) {
  endclass = tags[i].indexOf("\">");
  if (endclass > -1) {
    var newclass = tags[i].substring(0,endclass).split(" ");
    classes = classes.concat(newclass);
  }
}

Here is my jsfiddle: http://jsfiddle.net/nmkjvqmL/

This however, is assuming that the class is at the end of the tag. If it is not always at the end of the tag you can change this line: endclass = tags[i].indexOf("\">"); to this endclass = tags[i].indexOf("\""); However, this will include the string class="whatever" that is not in a tag, so you will have to make sure this text is not in the string.

Spencer May
  • 4,266
  • 9
  • 28
  • 48