I’ve asked this same question myself, but today I am finally taking the time to write about it.
Normally, people might think “I need to find out the x,y where the user clicked and see if that’s within the area of my element”. The answer is much easier than that.
On the Prototype API Docs for Event.element() they have a great example where they observe the document.body click event and find the element that was clicked using Event.element(). If the element clicked doesn’t match the one you’re comparing, then you have clicked “outside” of your element.
But what if your element has child elements? Since Event.element() will give you the element clicked on, it will not tell if that element is within the element you need to compare. That’s where Event.findElement() comes in to play. This method will accept a CSS expression (as of 1.6 RC0) to find a matching element. If Event.findElement() can not find the specified expression, then it will return undefined.
Let’s go through an example. You show a dialog (<div id="dialog">) in the middle of the screen. The dialog has a few child <p> elements. You want to find out when the user clicks “outside” (loses focus) to the dialog which results in closing/hiding the dialog.
Code:
Event.observe(document.body, 'click', function(e) { var el = Event.findElement(e, 'div#dialog'); if (el) el.hide(); });
That simply observes the click event on the document.body and when an element is clicked within the dialog div, it hides the dialog.
Hope this helps!
- Joe
Joe, you’re absolutely right about findElement, but you there seems to be a confusion about actual postition of an element on a PAGE and its position in a DOCUMENT order. Having one paragraph defined within another in html doesn’t mean that element is actually positioned within the parent on a page… To check actual page position you still need to calculate x/y bounds of both elements to see if they intersect… but for simple parent-child relationship, findElement is good enough.
Cheers,
kangax
Good point kangax! I’ve come up with this to answer your question:
I tested quickly and seems to work great!
– Joe