selecting root element in jquery

2019-02-21 23:02发布

问题:

I need to be able to select the root element from a fragment 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:

Whilst this question was answered a while ago perfectly correctly - I was just trying to attempt this myself and wasn't too keen on using a selector like *:not(* *) -- mainly because of the probable overheads. I don't know if this is a recent addition to jQuery's ability (i'm using 1.8) but you can use:

$(':eq(0)');

This will select the first found non-textnode element, so unless the dom you are traversing is illegal in it's formation, you should always get the root element. It is also highly optimal because jQuery should know to stop after the first element found.

So here's a little something for all of those WSOD fans out there:

$(':eq(0)').remove();

Oh and just in case it isn't obvious that the above code snippets were just illustrating the selector, and you find yourself working with a partial fragment (rather than the full document), then you should use this selector with jQuery's filter method:

$(fragment).filter(':eq(0)');

However, when working with fragments you can just do the following:

$(fragment).get(0);

Although bear in mind that .get(0) can select text/comment nodes if they are the first item in your document, whereas the filter approach will always find the first actual element.



回答2:

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.



回答3:

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()


回答4:

If you've got your elements as a jQuery fragment like:

var myElements = $('<div id="0">
<div id="0a">
    <div id="a01"></div>
</div>
<div id="0b">
</div>
<div id="0c">
</div>
</div>');

then you can find the first element by:

myElements.filter(":first")

The filter function looks from the root element of the fragment.



回答5:

jQuery is not needed...

var root = document.firstChild;


回答6:

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.



回答7:

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.



回答8:

I get html fragment from ajax call, and I also need to get the root div from it. What I did was simply call $(data), and jQuery will parse the returning text as HTML and give you the root.

$.ajax path,
  type: 'GET'
  contentType: 'application/x-www-form-urlencoded;charset=UTF-8'
  success: (data) ->
    $(data)


回答9:

If you want to select the top level parent of an element but still under the body, I'd go

$(obj).parents().filter('body > *')