0

I have a menu. When a tree is opened, it gets the class active. I wan't to get the deepest sub-menu of the menu with the class active.

2 Answers2

1

You can use the parents() collection to count the depth of the element and then return the lowest for the specific selector. Try this:

<div>
    1
    <div class="active">1.1</div>
    <div class="active">
        1.2
        <div class="active">
            1.2.1
            <div class="active">1.2.1.1</div>            
        </div>
        <div class="active">1.2.2</div>
    </div>
    <div class="active">1.3</div>
    <div class="active">
        1.4
        <div class="active">1.4.1</div>
        <div class="active">1.4.2</div>
    </div>
    <div class="active">1.5</div>
</div>
var $elems = $('.active'), $deepest, lowestLevel = 0;
$elems.each(function() {
    var depth = $(this).parents().length;
    if (depth > lowestLevel) {
        $deepest = $(this);
        lowestLevel = depth;
    }
});
$deepest.css('border', '1px solid #C00');

Example fiddle

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • I thank you, this is exactly what I wanted to do! One question, how do those comma separated variables work in $elems? I haven't seen anything defined like that before. –  May 30 '13 at 09:02
  • @Sergo It's just defining three different variables. I could have instead written it as: `var $elems = $('.active'); var $deepest; var lowestLevel = 0;` – Rory McCrossan May 30 '13 at 09:22
1

And a vanilla version :

function deepest (subMenu, select) { 
  return [].slice.call (subMenu.querySelectorAll (select)).reduce (
    function (deepest, el) {
      for (var d = 0, e = el; e !== subMenu; d++, e = e.parentNode);
      return d > deepest.d ? {d: d, el: el} : deepest;
    }, {d: 0, el: subMenu}).el;
 };

call with

deepest (subMenu, '.active');

where the second parameter selects the elements to be considered.

Tested on a modified version of @Rory's fiddle

HBP
  • 15,685
  • 6
  • 28
  • 34