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/.