Detect click with pure JavaScript

Here’s how to handle click events in vanilla JavaScript.

This is one of those note-to-self posts, as I learn vanilla JavaScript. Hopefully this is of help to other internet surfers, too.

I have found a few methods for detecting click events on a page.

onclick

The good old onclick property is from the original ECMAScript spec (IE 4 times):

var el = document.getElementById('module')
 
el.onclick = function () {
  console.log('Click just happened')
}

Or as extracted to a helper method for convenience:

var el = document.getElementById('module')
var clickerFn = function () {
  console.log('Click just happened')
}
 
el.onclick = clickerFn

Listen for clicks with addEventListener

This one is the modern solution:

var el = document.getElementById('module')
var clickHandler = function () {
  console.log('Click just happened')
}
 
el.addEventListener('click', clickHandler)

It won’t work in IE8 (who cares anymore though).

Detect click on a NodeList

For example, getElementById() gets one element, and onclick can listen to that element. The different ways to select those elements are covered in the JavaScript DOM query guide. But if multiple elements are queried with getElementsByClassName() or getElementsByTagName(), iteration is needed:

var els = document.getElementsByClassName('list--item')
 
for (var i = 0; i < els.length; i++) {
  // Here we have the same `onclick`
  els[i].addEventListener('click', function (event) {
    console.log('Element ' + event.target.innerHTML + ' was just clicked')
  })
}

That’s not too bad, but we’re adding multiple event handlers, with event propagation we can get away with just one event handler.

Event propagation

Let’s use the following test HTML:

<div id="wrap">
  <ul class="list">
    <li class="list--item">Foo</li>
    <li class="list--item">Bar</li>
    <li class="list--item">Baz</li>
  </ul>
</div>

We can listen for click events on the outer #wrap element and let them propagate down. Then we catch the elements we want and nothing more:

var wrap = document.getElementById('wrap')
 
wrap.addEventListener('click', event => {
  // Check if it’s the list element, we want the clicks only from them
  if (event.target.classList.contains('list--item')) {
    console.log('The item ' + event.target.innerHTML + ' was just clicked')
  }
})