views:

101

answers:

7

Hello,

I have a specific id ("mysubid"), now I want to check if this element (this id) is in a child path of an other id ("mymainid").

Is there an easy way to do this or will I go upwards, element by element, to see if the element is in a child path.

By child path I am talking about something like this:

A > B > C > D

So D is in the Child Path of A,B and C

+2  A: 
var isInPath = $("#mysubid").closest("#mymainid").length > 0;
dave thieben
+1  A: 
  if( $("#mymainid").find("#mysubid").length > 0 )
sathis
+1  A: 
if($('#mysubid','#mymainid').length)
{

}

This will check to see if #mysubid is within #mymainid

jQuery( selector, [ context ] )
  • selector: A string containing a selector expression
  • context: A DOM Element, Document, or jQuery to use as context

This is a just an overlaod for $('#mymainid').find('#mysubid').lentgh btw, verified from: http://github.com/jquery/jquery/blob/master/src/core.js#L162

On another note, using a method such as $('#a #b') resorts to using the Sizzle Selector witch is slower than doing $('#a',$('#b')), witch uses purely javascript's getElementById

Note: as jQuery returns an empty object by default if the selection is not found you should always use length.

RobertPitt
You're missing a `.length` on the end of that.
BBonifield
yes as you was writing that I was performing a test to see what distinct variables there was and forgot about `length`, witch returns `0 or greater` and 0 is boolean-able
RobertPitt
Your first jQuery call isn't valid syntax: see http://api.jquery.com/jQuery/#jQuery1. The context must be an element or jQuery object, not another selector.
kevingessner
Your wrong: see http://github.com/jquery/jquery/blob/master/src/core.js#L162
RobertPitt
http://stackoverflow.com/questions/1777719/what-is-the-definition-of-an-implementation-detail
kevingessner
@Robert: I think you better refer to line 171: http://github.com/jquery/jquery/blob/master/src/core.js#L171
Felix Kling
I never stated it was valid sir,I just know that this is mealy a an overload for `$('#a').find('#b')`, witch was also stated in my post, if the OP Wishes for STRICT Standards then I will be happy to change my answer to a method that has been implemented into the docs.
RobertPitt
@Felix, Line 171 refers to passing jquery objects like so: `var a = $('a');` followed by `$(a)`, this is never executed because using my method your passing in 2 strings, please refer to line 92: http://github.com/jquery/jquery/blob/master/src/core.js#L92
RobertPitt
+7  A: 

You all are making this very complicated. Use the descendant selector:

if ($('#mymainid #mysubid').length) {
    // #mysubid is inside #mymainid
}
kevingessner
+1 that is what i'd do - shortest and most efficient
Thariama
+1 Simple and direct. Great answer.
Alison
this uses Sizzle engine and unneeded regex test, you *can* use `$('#mymainid',$('#mysubid')).length` which relies purely on `getElementById` :)
RobertPitt
@RobertPitt - I'm not sure about that. A quick bit of Firebug testing shows that the descendant selector is waaay faster than using context: 1.28ms per call v. 14.5ms per call (500 iterations each, Firebug 1.5.4 in Firefox 3.6.10).
kevingessner
then i may be wrong, I have not fully profiled the code, I have taken a look into the source and that's what it shows, I will look into that soon, thanks.
RobertPitt
A: 

Using the 'is' method actually returns a boolean.

if($('#mymainid').is(':has(#mysubid)')) // true

Going the other direction...

if($('#mysubid').parents('#mymainid').length) // 1
Josiah Ruddell
+1  A: 

If you want to see the entire chain as an array use elm.parentNode and work backwards. So, to answer your question (and the depth or distance between the elements) in POJ, you can use:

var doc = document,
child = doc.getElementById("mysubid"),
parent = doc.getElementById("mymainid"),
getParents = function (elm) {
    var a = [], p = elm.parentNode;
    while (p) {
        a.push(p);
        p = p.parentNode;
    }
    return a;
};
getParents(child).indexOf(parent);
AutoSponge
I learned the `indexOf` on an array with your answer. Thanks!
Mic
+1  A: 

I tried on various browsers and the DOM function below is between 3 to 10 times faster than the selector methods(jQuery or document.querySelectorAll)

    function is(parent){
        return {
            aParentOf:function(child){
                var cp = child.parentNode;
                if(cp){
                    return cp.id === parent.id ? 
                       true : is(parent).aParentOf(cp);
                }
            }
        }
    }

The call below will return true if A is a parent of D

is(document.getElementById('A')).aParentOf(document.getElementById('D'))

For just few calls I would use the $('#A #D').length
For very frequent calls I would use the DOM one.

Mic