开发者

Check if an element is a child of a parent

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 happ开发者_C百科en whenever I click on anywhere.

Is there something wrong with my code?


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');
    }
}


.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');
}


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>


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.


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')
});


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.


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>


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜