November 2007
Posted on the 13th at 10:59 PM CST
Determine if any Other Outside Element was Clicked with Javascript
FiledFiled under Javascript

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

Comments (4)
Permalink Comment from SeanEmail on November 15th, 2007 at 2:58 PM
That's a neat trick. It would come in handy for things like Modal Popups that you want to close if the User clicks outside of the popup area.
Permalink Comment from BoB Frendo on May 18th, 2008 at 6:39 AM
This doesn't work in firefox
Permalink Comment from Pavlo Hrizhynku on July 10th, 2008 at 7:26 AM
I changed almost nothing in the code and it works with firefox! just caught the event in the document.onclick = function function and passed it to clickedOutsideElement function where I did something more and it works. I will paste the code here, but I don't know how to format it so that it will show as code should show on this page.

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!');
}
Permalink Comment from Josh StodolaEmail on July 10th, 2008 at 7:33 AM
Thanks alot, Pavlo!

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

Have Your Say

← Answer this to prove you are human
 
 

Chill Out…

No Trackbacks