# 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):

```js
var el = document.getElementById('module')

el.onclick = function () {
  console.log('Click just happened')
}
```

Or as extracted to a helper method for convenience:

```js
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:

```js
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](/getting-dom-elements-with-javascript). But if
multiple elements are queried with `getElementsByClassName()` or
`getElementsByTagName()`, iteration is needed:

```js
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:

```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:

```js
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')
  }
})
```
