Question

How can you get javascript (or jquery if it's eaisier) to return an array, starting with elements that have the fewest parents, then 2nd fewest, 3rd fewest... and so on

So that a DOM like this below

<div class="first">
  <div class="second">
    <div class="third"></div>
    <div class="fourth">
      <div class="fifth"></div>
    </div>
  </div>
  <div class="sixth"></div>
  <div class="seventh">
    <div class="eighth"></div>
  </div>
  <div class="ninth"></div>
</div>
<div class="tenth"></div>

Would return an array like this...

["first", "tenth", "second", "sixth", "seventh", "ninth", "third", "fourth", "eighth", "fifth"]
Was it helpful?

Solution

This works:

var $first = $('body').children('div'),          // Finds the first level
    output = [];                                 // Stores the results

while ($first.length != 0) {                     // While we still can go deeper
    output = $.merge(output, assemble($first));  // Get the classes on this level
    $first = $first.children('div');             // Dive deeper
}

console.log(output);                             // Output the results        

function assemble(l) {                           // Collects classes at a level
    var arr = [];
    $.each(l, function() {
        arr.push($(this).attr('class'));
    });
    return arr;
}

DEMO

OTHER TIPS

jsFiddle Demo

Using a parent reference, iterate recursively through the children and record the depth. Order these records by depth and then return an array of the class names. jQuery was less verbose, shown here is an extension method for jQuery to do this starting from a container.

$.fn.classByDepth = function(){
 var elements = [];
 (function children(top,depth){
  top.children().each(function(){
    var element = {
        name: this.className,
        depth: depth
    };
    elements.push(element);
    children($(this),depth+1);
  });
 })(this,1);
 elements.sort(function(left,right){
   if(left.depth<right.depth)return -1;
   if(left.depth>right.depth)return 1;
   return 0;
 });
 var ordered = [];
 $.each(elements,function(){
   ordered.push(this.name); 
 });
 return ordered;
};

Used:

//assuming that #container was a div containing your example html structure
console.log($("#container").classByDepth());
//["first", "tenth", "second", "sixth", "seventh", "ninth", "third", "fourth", "eighth", "fifth"] 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top