Check if an element is a child of a parent

JavascriptJquery

Javascript Problem Overview


I have the following code.

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>

<div id="hello">Hello <div>Child-Of-Hello</div></div>
<br />
<div id="goodbye">Goodbye <div>Child-Of-Goodbye</div></div>

<script type="text/javascript">
<!--
function fun(evt) {
    var target = $(evt.target);    
    if ($('div#hello').parents(target).length) {
        alert('Your clicked element is having div#hello as parent');
    }
}
$(document).bind('click', fun);
-->
</script>

</html>

I expect only when Child-Of-Hello being clicked, $('div#hello').parents(target).length will return >0.

However, it just happen whenever I click on anywhere.

Is there something wrong with my code?

Javascript Solutions


Solution 1 - Javascript

If you are only interested in the direct parent, and not other ancestors, you can just use parent(), and give it the selector, as in target.parent('div#hello').

Example: http://jsfiddle.net/6BX9n/

function fun(evt) {
    var target = $(evt.target);    
    if (target.parent('div#hello').length) {
        alert('Your clicked element is having div#hello as parent');
    }
}

Or if you want to check to see if there are any ancestors that match, then use .parents().

Example: http://jsfiddle.net/6BX9n/1/

function fun(evt) {
    var target = $(evt.target);    
    if (target.parents('div#hello').length) {
        alert('Your clicked element is having div#hello as parent');
    }
}

Solution 2 - Javascript

.has() seems to be designed for this purpose. Since it returns a jQuery object, you have to test for .length as well:

if ($('div#hello').has(target).length) {
   alert('Target is a child of #hello');
}

Solution 3 - Javascript

Vanilla 1-liner for IE8+:

parent !== child && parent.contains(child);

Here, how it works:

function contains(parent, child) {
  return parent !== child && parent.contains(child);
}

var parentEl = document.querySelector('#parent'),
    childEl = document.querySelector('#child')
    
if (contains(parentEl, childEl)) {
  document.querySelector('#result').innerText = 'I confirm, that child is within parent el';
}

if (!contains(childEl, parentEl)) {
  document.querySelector('#result').innerText += ' and parent is not within child';
}

<div id="parent">
  <div>
    <table>
      <tr>
        <td><span id="child"></span></td>
      </tr>
    </table>
  </div>
</div>
<div id="result"></div>

Solution 4 - Javascript

If you have an element that does not have a specific selector and you still want to check if it is a descendant of another element, you can use jQuery.contains()

> jQuery.contains( container, contained )
> Description: Check to see if a DOM element is a descendant of another DOM element.

You can pass the parent element and the element that you want to check to that function and it returns if the latter is a descendant of the first.

Solution 5 - Javascript

Ended up using .closest() instead.

$(document).on("click", function (event) {
    if($(event.target).closest(".CustomControllerMainDiv").length == 1)
    alert('element is a child of the custom controller')
});

Solution 6 - Javascript

You can get your code to work by just swapping the two terms:

if ($(target).parents('div#hello').length) {

You had the child and parent round the wrong way.

Solution 7 - Javascript

Without jquery

target.matches() with :scope

If you want to see if the target element has a parent which matches some selector use the .matches() method on the target and pass the selector followed by the :scope pseudo class.

The :scope here refers to the target element so you can use the in a :where pseudo class to help you write out a clean selector.

In the following example we will match all target elements which are a decedent of an a, button, or summary element.

const app = document.getElementById("app");

app.addEventListener("click", (event) => {
  if (
    event.target.matches(
      ":where(a, button, summary) :scope"
    )
  ) {
    console.log("click", event.target.parentNode.tagName);
  }
});

<div id="app">
  <button>
    <span>Click Me</span>
  </button>

  <a href="#">
    <span>Click Me</span>
  </a>
  
  <details>
    <summary>
      <span>Click Me</span>
    </summary>
  </details>
  
  <span>Click Me</span>
<div>

Note the selector :where(a, button, summary) :scope could also have been written as:

a :scope,
button :scope,
summary :scope

parent.contains()

If you are interested in seeing if the target element is a child of a specific element use .contains() on the potential parent element:

const app = document.getElementById("app");
const button = document.getElementById("button");

app.addEventListener("click", (event) => {
  if (button.contains(event.target)) {
    console.log("click");
  }
});

<div id="app">
  <button id="button">
    <span>Click Me</span>
  </button>
  
  <span>Click Me</span>
<div>

Solution 8 - Javascript

In addition to the other answers, you can use this less-known method to grab elements of a certain parent like so,

$('child', 'parent');

In your case, that would be

if ($(event.target, 'div#hello')[0]) console.log(`${event.target.tagName} is an offspring of div#hello`);

Note the use of commas between the child and parent and their separate quotation marks. If they were surrounded by the same quotes

$('child, parent');

you'd have an object containing both objects, regardless of whether they exist in their document trees.

Solution 9 - Javascript

To know more background info on Aleksandr Makov's answer, checking the below page might be helpful.

https://developer.mozilla.org/en-US/docs/Web/API/Node/contains

> Node.contains()
> The contains() method of the Node interface returns a boolean value indicating whether a node is a descendant of a given node, that is the node itself, one of its direct children (childNodes), one of the children's direct children, and so on.

It means, the answer is not using a reclusive function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCheok Yan ChengView Question on Stackoverflow
Solution 1 - Javascriptuser113716View Answer on Stackoverflow
Solution 2 - JavascriptBlazemongerView Answer on Stackoverflow
Solution 3 - JavascriptAleksandr MakovView Answer on Stackoverflow
Solution 4 - JavascriptnaitsirchView Answer on Stackoverflow
Solution 5 - JavascriptLukasView Answer on Stackoverflow
Solution 6 - JavascripttttpppView Answer on Stackoverflow
Solution 7 - JavascriptRúnar BergView Answer on Stackoverflow
Solution 8 - JavascriptI Want AnswersView Answer on Stackoverflow
Solution 9 - JavascriptJay CaseeView Answer on Stackoverflow