JavaScript/jQuery: hasDescendant / hasAncestor

749 views Asked by At

Hilariously, I'm having incredible difficulty finding any half-good way to determine whether or not an HTML element is inside another one or not -- which seems like it should be a basic core feature of traversing and analyzing the HTML DOM. I was immensely surprised and disappointed that the "hasDescendant" (or likewise) method is missing.

I'm trying to do this:

var frog = $('#frog');
var walrus = $('#walrus');
if (frog.hasDescendant(walrus)) console.log("Frog is within walrus.");
else console.log("Frog is outside walrus.");



I've tried to reproduce what I'm looking for with many jQuery combinations.

walrus.is(frog.parents());
walrus.has(frog);
walrus.find(' *').has(frog);
frog.is(walrus.find(' *'));



I haven't found a working solution yet.


[edit]
Solution: walrus.has(frog)
Alternate: if (walrus.has(frog)) { doStuff(); }
Alternate: var booleanResult = walrus.has(frog).length>0;


//Chase.

3

There are 3 answers

0
Gabriele Petrioli On BEST ANSWER

Use

if (walrus.has(frog).length) {
  // frog is contained in walrus..
}

Demo at http://jsfiddle.net/gaby/pZfLm/


An alternative

if ( $('#frog').closest('#walrus').length ){
      // frog is contained in walrus..
}

demo at http://jsfiddle.net/gaby/pZfLm/1/

0
nnnnnn On

If you wanted to write your own function you could do it without jQuery, perhaps something like this:

function isAncestor(ancestor, descendent) {
   while ((descendent = descendent.parentNode) != null)
      if (descendent == ancestor)
         return true;

   return false;
}
2
T.J. Crowder On

jQuery has just the function for this: jQuery.contains: "Check to see if a DOM element is within another DOM element."

Demo (live copy):

HTML:

<p id="frog">Frog <span id="walrus">walrus</span></p>

JavaScript:

jQuery(function($) {
  var frog = $("#frog"),
      walrus = $("#walrus");

  display("frog contains walrus? " + $.contains(frog[0], walrus[0]));
  display("walrus contains frog? " + $.contains(walrus[0], frog[0]));

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});