What is the difference between the Descendant selector and the :has selector?
From the documentation:
Descendant selector
Description: Selects all elements that are descendants of a given ancestor.
A descendant of an element could be a child, grandchild, great-grandchild, and so on, of that element.
:has
Description: Selects elements which contain at least one element that matches the specified selector.
The expression
$('div:has(p)')
matches a<div>
if a<p>
exists anywhere among its descendants, not just as a direct child.
Even after reading the explanation, the difference is not clear to me. Can someone help me understand?
The descendant selector in
div p
selects thep
descendants of thediv
.The
:has()
selector indiv:has(p)
selects thediv
if it contains anyp
elements.The bold parts are all you need to know. The rest can be seen as mere conditions as to which elements of those types are selected.
In CSS selector terms, the key selector is the right-most outer simple selector. The kind of elements that get picked up by jQuery (or by a browser's CSS parser) is the one in the key selector.
In the first selector, the key is
p
, because it's the right-most one, occurring after the descendant combinator (the space). This means a collection ofp
elements will be returned.In the case of
:has()
, which is a pseudo-class, thep
is an "inner" simple selector that is part of the:has()
pseudo-class, not part of the entire "outer" selector. The key in that selector is thereforediv
, notp
. This means a collection ofdiv
elements will be returned, rather thanp
elements in the first selector.The
descendants
-selector will select the actual descendants, while the:has
-selector will select the parent element(s) that contain the element within the has().