2

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.

ChaseMoskal
  • 7,151
  • 5
  • 37
  • 50

3 Answers3

4

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);
  }
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Immediately after reading this answer, I implemented `$.contains` into my project, and was surprised to find that it was failing on me under certain circumstances that I did not expect. I didn't have time to fully figure it out, but I **think** some dynamic content added with `$(element).html(newContent);` was failing to attach itself to the DOM properly (causing HTMLElement.parentNode to == null, furthermore causing `$.contains` to fail). It was creepy because I had `$.contains` returning results that were in direct contradiction with what I could see in the firebug DOM view. – ChaseMoskal Nov 14 '11 at 06:18
  • @ChaseMoskal: See my comment on the question. – T.J. Crowder Nov 14 '11 at 08:41
2

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/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
2

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;
}
nnnnnn
  • 147,572
  • 30
  • 200
  • 241