In Javascript, it is very easy to handle the click event of an element and perform any given operation when it gets clicked. However, what if you need execute some code if/when the user clicks an element outside of that element? This is not your everyday scenario, but I stumbled upon it again the other day and thought I would make a post out of it. When I first ran into this problem a year or so ago, I wasn't sure how to approach it. Initially, I thought I would have to monitor mouse coordinates. That became a very ugly solution in a heartbeat. Fellow forum follower and Javascript/AJAX author Eric Pascarello hooked me up with an idea that works fantastic. First consider the following markup...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Detect When Anything Else was Clicked in Javascript</title> <script type="text/javascript" src="click.js"></script> <style type="text/css"> body { background-color:green; margin:0px; padding-top:100px; } div.test { border:solid 2px white; background-color:blue; color:yellow; height:350px; margin:auto; width:350px; } </style> </head> <body> <div id="divTest" class="test"> Test Element </div> </body> </html>
It's nothing but a simple box in the middle of the page that I will use to test. In order to monitor the click event for the entire page, we need to assign an event handler to the onclick of the document. Then we simply determine the ID of the element that was clicked, and loop through all of its parent element(s). Then just compare each parent elements ID with the ID that was passed to the function. If it finds a match, then they must have clicked inside the element. Here is the final Javascript file (click.js)...
function clickedOutsideElement(elemId) { var theElem = getEventTarget(window.event); while(theElem != null) { if(theElem.id == elemId) return false; theElem = theElem.offsetParent; } return true; } function getEventTarget(evt) { var targ = (evt.target) ? evt.target : evt.srcElement; if(targ != null) { if(targ.nodeType == 3) targ = targ.parentNode; } return targ; } document.onclick = function() { if(clickedOutsideElement('divTest')) alert('Outside the element!'); else alert('Inside the element!'); }
I had to setup a separate function to get the event target element to make it work in all modern browsers. The part where it checks the nodeType to be 3 is to correct a Safari bug. Having to write functions like this really get me excited about the next version of ECMAScript (version 4).
function clickedOutsideElement(elemId, evt) {
alert(evt);
var theElem = '';
if(window.event)
theElem = getEventTarget(window.event);
else theElem = getEventTarget(evt);
while(theElem != null) {
if(theElem.id == elemId)
return false;
theElem = theElem.offsetParent;
}
return true;
}
function getEventTarget(evt) {
var targ = (evt.target) ? evt.target : evt.srcElement;
if(targ != null) {
if(targ.nodeType == 3)
targ = targ.parentNode;
}
return targ;
}
document.onclick = function(evt) {
if(clickedOutsideElement('divTest', evt))
alert('Outside the element!');
else
alert('Inside the element!');
}
Guess What?
There are a few basic guidelines you should be aware of before leaving a comment…
- If you choose to display your email address, it will not be detected by spam bots
- Comments are limited to 3,000 characters; so far you have used none of them
- HTML will be encoded; links and line breaks will be converted automatically
- Comments containing five or more links will be subject to moderation
