tags:

views:

87

answers:

5
<div class="top">
    <div class="branch">
        <div class="branch">
             <div class="leaf">click</div>
        </div>
    </div>
</div>

When I click on the inner most <div class="leaf">,how to get all its way from top to itself:

top,branch,branch,leaf

EDIT to clarify I want to have the path in an array:

arr[0]='top';
arr[1]='branch';
arr[2]='branch';
arr[3]='leaf';

Is there an easy solution?

A: 

this is an entire section in the jquery documentation that describes how to traverse the dom. check it out here http://docs.jquery.com/Traversing

darren
+1  A: 

if you want to go up to the parent, use the parent() call

http://docs.jquery.com/Traversing/parent

you may also like parents(), which will return to you a list of all the parents:

http://docs.jquery.com/Traversing/parent

if you want to go down, you'll have to use the children() [for your case, each item only has one child]

http://docs.jquery.com/Traversing/children#expr

general traversing options in jquery:

http://docs.jquery.com/Traversing

santosc
A: 
$('div.leaf').click(function() {
   $(this).parents('div.top'); // This will get you the top-level div
   $(this).parents('div.branch'); // This will get you all the branches
});

EDITED

This assumes of course that there aren't other div.top and div.branch that are parents of the tree you specified.

Dominic Barnes
+3  A: 

a simple $('.leaf').parents().get() will give you an array of all the parents in reverse order.

$('.leaf').add($('.leaf').parents()).not(':has(.top)').get().reverse().map( function(e) {
    return $(e).attr('class');
});

will give you the array you want.

This is probably of significant enough complexity that it would be worth making it a plugin if you plan on using it much.

cobbal
I need it to terminate once `top` is found
updated (15 chars)
cobbal
It returns something like this:`,,branch,branch`.I don't know why...
updated again (tested this time)
cobbal
My final version is a combination of yours and Doug Neiner's.
I decided to accept Doug Neiner's,but +1 for your answer
+4  A: 

This will do what you want. The console.log statement is for Firebug. Just replace it with your code that uses the array.

$(".leaf").click(function(){
   var $this = $(this),
       array = $.map(
         $this.add($this.parents(':not(:has(div.top))')), 
         function(n){ return n.className }
       ).reverse();

   console.log( array );
});

Will output this when clicked:

["top", "branch", "branch", "leaf"]

Update

To exclude top from the result, just change the selector a bit:

$(".leaf").click(function(){
   var $this = $(this),
       array = $.map(
         $this.add($this.parents(':not(:has(div.top)):not(div.top)')), 
         function(n){ return n.className }
       ).reverse();

   console.log( array );
});

Will output this when clicked:

["branch", "branch", "leaf"]
Doug Neiner
How to exclude `top` from the result?
I updated my answer to show how to exclude top.
Doug Neiner
I tried `:not(:has(div.top)), :not(div.top)`,but not working as expected.Seems `,` means `or`,not `and`?
You are right... sorry! I was saying OR instead AND. Please try the updated selector. I have tested it and it works as expected.
Doug Neiner
It works this time.But BTW is there a simbol that means `and` in jQuery?
No, you just chain the selectors together. `.top, .leaf` means `.top` or `.leaf` or both, where `.top.leaf` means has *both* `.top` *and* `.leaf` classes.
Doug Neiner
`:not(:has(div.top), div.top)` would also work by De Morgans
cobbal
@cobbal,nice,checked in