Derek's suggestion is nice but not fully reliable since .closest('li')
is likely to find a list item in which #foo
might be contained. Besides, in this case .length > 0
will always be true
.
That being said, there is no need to traverse up the DOM tree using .closest()
. Indeed, we already know that the handler will be called only if #foo
or one of its descendants is clicked, so, we just need to check whether the clicked element (event.target
) is #foo
(this
) :
$('#foo').click(function (e) {
if (e.target === this) {
// #foo was clicked directly
} else {
// something inside of #foo was clicked
}
});
However, .closest()
could be useful to retrieve a particular element inside of #foo
. Let's say we want the direct LI that was clicked in order to add a selected
class to it :
$('#foo').click(function (e) {
var item;
if (e.target === this) {
// #foo was clicked directly
} else {
// something inside of #foo was clicked
// 3 options to find the related item :
// option 1 - easy to read
item = $(e.target).closest('#foo > li');
// option 2 - useful if the container has no ID
item = $(e.target).closest($(this).children());
// option 3 - probably the fastest one
item = e.target;
while (item.parentNode !== this) item = item.parentNode;
item = $(item);
item.addClass('selected');
}
});
Here is a demo : http://jsfiddle.net/wared/dE6Pj/.
Documentation : http://api.jquery.com/closest/.