views:

938

answers:

5

I need to be able to select the root element without knowing the node types, class, id or hierachy.

<div id="0">
    <div id="0a">
        <div id="a01"></div>
    </div>
    <div id="0b">
    </div>
    <div id="0c">
    </div>
</div>

I want to be able to do something like $(':root') and have 0 selected in the example above.

Better still I would prefer $(':level(0)') which would mean the same as above, $(':level(1)') would select 0a, 0b and 0c and $(':level(1)>div') would select a01.

Any ideas on how to do it neatly?

+1  A: 

I'm more of a Prototype guy, but I think you could get all the nodes then get the first node in the array:

$('*')[0]

Then get the child items of that (for 0a, 0b and 0c)

$('*')[0].children()
adam
so far this looks like the best solution, will have to have a think
Sqoo
+1  A: 

jQuery is not needed...

var root = document.firstChild;
Josh Stodola
promissing idea, although I may be doing this from a current jQuery selection, so I really need a way of doing it from jQuery
Sqoo
Dear God..... I think you should learn how that library works before using it. I don't understand how any programmer can feel comfortable just blindly using a library. If you want to turn this into jQuery, it's as simple as this: `$(document.firstChild)`
Josh Stodola
Not what I meant, but cheers for your concern :(
Sqoo
@Sqoo: `$('div')[0].ownerDocument.firstChild`. Learn JavaScript. jQuery is no magical fairy dust you sprenkle onto your website.
Boldewyn
@Boldewyn, this was not a general JavaScript query, this was specifically a question about jQuery selectors. Why are you wasting your time writing rude comments when you don't even understand the question?
Sqoo
A: 

you could look into using the parent() and children() functions. is you need to go multiple levels , you can chain them like so.

$("#a01").parent().parent()  //returns <div id="0">

please see my comment, and I'll try to give a better solution.

GSto
thing is I wont know any ids, classes or node types, so I cant use a selector like '#a01'
Sqoo
+1  A: 

OK, so what you need to do is the following (presuming that you are using the sample you've got), if you want to find the top level node using jquery is the following:

 $('*:not(* *)');

What you are literally asking for here is for all nodes that are not children of other nodes. The problem is that for a html document, this will always give you only the html element, which isn't particularly useful. So, if you want to find the top level element within the body of a html document, you'd use something a lot simpler:

 $('body > *');

if you then wanted the second level, you'd just go

 $('body > * > *');

But, presuming you have some sort of arbitrary document structure (like the foo one you mention), what you can do is use the first example to find the first level:

 $('*:not(* *)');

and then for the second level

 $('*:not(* *)').find('> *');

and for the third level

 $('*:not(* *)').find('> * > *');

and so on and so forth. If you're looking for a root div element (presuming that your sample is like the question), you can do this:

 $('div:not(div div)');

and so on, replacing * with div. Not really sure why you'd want to do this, but it will work. The problem is the question doesn't really provide enough context for us to give you a better alternative.

Deeksy
For the particular foo example mentioned in the comments, it's $('foo:not(foo foo)');
Deeksy
$('*:not(* *)'); Was exactly what I was after, and came close myself not didnt quite get it right. The examples using BODY were all things I couldnt do as I had no idea what was contained within the tree (it could be *any* snippet including arbitary XML) :)
Sqoo
Also thank you for understanding the question, that is that I wanted a jQuery selector and not a piece of JS code (I know how easy this can be done in JS)
Sqoo
A: 

I may be misunderstanding the question, but assuming by root you mean the point at which the parent is a different tag to the child then the following should work.

function GetRoot(element) {
    while(element.parent().attr("tagName") == element.attr("tagName")) {
        element = element.parent();
    }

    return element;
}

This basically walks up the tree until it finds a parent that is a different tag and then returns the item. For your example that would mean that if your element was in a , , or whatever it would detect it as the root and return it.

Making a custom jquery selector with this should be possible too, but is obviously more complicated.

It should also be fairly easy to extend this to take an integer that defines the level. All you'd need to do is walk down the tree to the specified depth once you've found the root and return those elements.

Nikolas Stephan