Lesson 10: JS Event Listeners

Kerry Powell
Web Development For Beginners
4 min readJul 25, 2017

JavaScript enables users to interact with your website. You can enable interaction by listening to user events. There are a myriad of pre-defined events including click, hover, blur, and focus. A list of events can be found here.

While developing for events, remember that there are styles and accessibility attributes to use in conjunction with attaching event listeners to elements. While using event listeners can make your site more interactive, you can also make your site less usable if you do not provide the correct styles and accessibility measures.

For most users, simple styling will be enough to make your site usable. For visually impaired users you may need to make some adjustments. In general if you are using HTML elements for their intended purpose you do not need to worry. For example, if you attach a click event to something that is not a button or link you will need to insert an ARIA attribute on the HTML element describing what the behavior of the element is. To learn more about ARIA attributes follow this link.

A Simple Example

The most simple example is a click event:

HTML

<button class="alertButton">Click Me</button>

JS

document.querySelector('.alertButton').addEventListener('click', (e) => {
alert('You clicked the button!');
})

Here we have a basic HTML button with a class. In the JavaScript file we first select the element by calling document.querySelector('.alertButton') where .alertButton is the class we used in the HTML. This method returns a JS element representation of the HTML element. The JS element contains a method of addEventListener which takes 2 arguments. The first argument is the event name, click in the example. The second argument is a function that is called when the event is triggered by the user.

In JavaScript, dot notation allows us to call a method of a previously returned function. In the example querySelector returns an object with another function of addEventListener . We simply call addEventListener on the same line of code.

A JavaScript file is included in a webpage by including the following tag in the HTML: <script src="myJSFile.js"></script> where “myJSFile.js” is the url of the JavaScript file. Script elements should be included at the end of the HTML file, right before the </html> tag for performance reasons.

An Accessibility Example

Tab panels are some of the least desirable UI options available and they tend to be a bit tricky when it comes to accessibility. That being said, chances are you will be asked to develop one sooner or later. Here is an example:

HTML

<div class="tabs">
<a class="tab" href="#yoda" data-active="true" aria-controls="yoda" role="tab" id="yodaTab">Yoda</a>
<a class="tab" href="#luke" aria-controls="luke" role="tab" id="lukeTab">Luke</a>
<a class="tab" href="#chewbacca" aria-controls="chewbacca" role="tab" id="chewbaccaTab">Chewbacca</a>
</div>
<div class="panels">
<div class="panel" id="yoda" data-active="true" aria-labelledby="yodaTab" role="tabpanel">
<img src="https://boygeniusreport.files.wordpress.com/2015/08/yoda.jpg?quality=98&strip=all"/>
</div>
<div class="panel" id="luke" aria-labelledby="lukeTab" role="tabpanel">
<img src="http://i1.mirror.co.uk/incoming/article9603913.ece/ALTERNATES/s1200/PROD-Luke-Skywalker-in-Star-Wars-film.jpg"/>
</div>
<div class="panel" id="chewbacca" aria-labelledby="chewbaccaTab" role="tabpanel">
<img src="https://vignette1.wikia.nocookie.net/starwars/images/7/72/Chewie19BBY-CVD.jpg/revision/latest?cb=20070221012454"/>
</div>
</div>

A couple things to notice here. First the use of aria-controls and aria-labelledby in conjunction with the ids of the tabs and panels. These tell screen readers what elements are controlled by other elements. Second, the use of the role attribute. This attribute tells screen readers what an element is.

CSS

.tabs {
border-bottom: 1px solid #333;
margin-bottom: 20px;
}
.tab {
display: inline-block;
border: 1px solid #333;
padding: 10px;
text-decoration: none;
font-family: arial, helvetica, sans-serif;
color: #333;
border-bottom: 0;
}
.tab[data-active=true] {
background: #eee;
}
.panel {
display: none;
width: 500px;
overflow: hidden;
padding: 0 40px;
}
.panel[data-active=true] {
display: block;
}
img {
max-width: 100%;
}

Not much to tell here, we just do some basic styling. We hide and show the tab panels based on the data-active attribute, and apply styling to the active tab by doing the same.

JS

let tabs = [...document.querySelectorAll('.tab')],
tabChange = function(ev) {

ev.preventDefault();
[...document.querySelectorAll('[data-active=true]')].map(active => {
active.setAttribute('data-active', 'false');
})
ev.target.setAttribute('data-active', 'true');
document.querySelector(ev.target.getAttribute('href')).setAttribute('data-active', 'true');
};
tabs.map(tab => {
tab.addEventListener('click', tabChange)
});

Here we do a bit more with click events. We start out by selecting all elements with a class of .tab and storing them in a variable.

Notice the use of the spread operator [...document.querySelectAll('.tab')] the spread operator is used to transform a data object into an array. We do this so that we can use array methods/functions to map over the returned object.

We then define a function that will be called when a tab is clicked. The function first prevents the default action of the event, because it is a link we don’t want the page to refresh or scroll. The function then selects all elements with an attribute of data-active=true and sets the attribute data-active to false for each of them. Then it sets the data-active attribute of the clicked element to true . It then queries the document for an element with an id of the clicked elements href attribute and sets its data-active attribute to true also.

All that is left is to attach the event listener to each tab. We call the map method of the tabs array, that we defined on the first line, to iterate over it. For each tab we call the addEventListener function we used in the first example and instead of using an anonymous function we pass in the name of the function that we defined earlier.

To view a pen of this example go here

Events are powerful, and can make or break a webpage. They enable your users to interact and be involved in the experience of your site. Next up we will deep dive into array methods and functions.

--

--

Kerry Powell
Web Development For Beginners

Front-End developer working at the Church of Jesus Christ of Latter-day Saints.