Clicking on or off an Element

One common task with JavaScript is toggling something in your web page. This toggle can be worked in several different ways - for example clicking on a particular element that makes another piece of the page appear or disappear (depending on its current state). Here we are going to consider a slightly more complex toggle - where clicking on a particular element toggles it one way and clicking anywhere in the page except on that element toggles it the other way.

We can do this using a single event listener attached to the body of the page, We can then simply test where in the page was clicked in order to determine whether the click was inside or outside of the designated element.

Let's start with the following JavaScript:

containsClick = function(outer, p) {
if (!p) return false;
while (p.tagName != 'BODY')  {
   p = p.parentNode;
   if (p.id == outer) return true;
   }
return false;
};

This function accepts an id as the first parameter and an element as the second. The id we pass as the first parameter will be the id that we have attached to an element in the page to distinguish the one that we are using for this toggle. There can be multiple elements inside of this one as well as lots of elements outside of it so this function takes the element passed to it in the second parameter and searches up the document tree until it either finds the one with the id attached (in which case it is inside that element) or reaches the body tag (in which case it is outside of that element. The function returns true or false depending on which of these applies.

Here's a simple example of its use. In this HTML we have a div with an id of 'blocka'. A click on any of the content of that element will replace the text in the first paragraph with 'in block' while a click anywhere else in the page will restore that paragraph to its original text. Note that multiple clicks inside or outside of the block will still run the code but will appear to have no effect as they will set the same value as is already there.

Note that the second parameter to our function is initially set to e.target which is the element that was the actual target of the event when it was triggered prior to the event propagating outward to run the code when it reached the body tag where this listener is attached.


<body>
  <p id="message">no</p>
  <p>another</p>
  <div id="blocka">
    <p>blocked one</p>
    <p>blocked <span id="here">click</span> two</p>
  </div>
  <p>yet another</p>
<script type-"application/javascript">
(function() {

var containsClick = function(outer, p) {
if (!p) return false;
while (p.tagName != 'BODY')  {
   if (p.id == outer) return true;
   p = p.parentNode;
   }
return false;
}; 

var myClick = function(e) {
var mess = document.getElementById('message');
if (containsClick('blocka',e.target)) mess.innerHTML = 'in block';
else mess.innerHTML = 'no';
    };
  
document.body.addEventListener('click', myClick, false );
}());
</script>
</body>

One additional things to note. Because we are using an event listener this code does not interfere with any other click processing added to the page that is also using an event listener. Those other event listeners can potentially interfere with the operation of this listener if they cancel the bubbling of the click event before it reaches the body tag.

 

This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow
Donate