Gentle ripples of blue water in front of a horizon at dawn

As it loads and is read, every web page fires a cascade of events in JavaScript, with even more fired if the user interacts with the page in any way. A browser loading a page or being scrolled is an event; so to is clicking on a button or filling out a form element. Any event that is “fired” in JavaScript can trigger code that you design and write to create deeper interactivity.

JavaScript events can be divided into four broad groups:

  1. UI Events: occur when a user interacts with the browser UI - the i.e. the controls surrounding the page that are part of the browser, rather than the web page itself, or actions that the page takes independent of the user. Includes events such as the user resizing or scrolling the browser window, or the web page loading or unloading content.
  2. Keyboard, mouse and touch events: occur when the user presses or releases a key on the keyboard, or uses the mouse, trackpad, or touchscreen.
  3. Focus and form events. Most commonly associated with forms: an <input> “gains focus” when the user is prepared to interact with it; other events track the submission of a form, changing a value in a form field, etc
  4. Mutation events and observers. Mutators track when the DOM is altered: for example, when elements are inserted or removed from a page with a script.

Binding

Creating code that responds to a particular event on a chosen DOM element - known as “binding” an event to the element - creates an event handler. There are three ways to create event handlers in JavaScript:

  1. Traditional HTML Event Handler via Attributes

    The oldest method of binding events, and one that you’ll still see used in a lot of code; uses specialized attributes inside markup. For example:

    <input type="text" id="username" onblur="checkName()">

    In the example above, after the input has been selected and the user moves on (for example, pressing the TAB key or clicking in another input), the element will call the checkName function written in your JavaScript.

    Traditional HTML event handers are no longer recommended for modern development, primarily because it places functionality in the same place as markup, making it much harder to maintain and debug your code.

  2. Traditional DOM Event Handlers

    This technique separates JavaScript from your markup, but has the same limitation that events can only be associated with a single function. The equivalent to the HTML event handler above, written as a DOM event handler in a script, would be:

    var username = document.getElementbyId("username");
    username.onblur = checkName;

    As before, removing focus from the form element would cause the function checkName to be run.

  3. Event Listeners

    The modern method of adding an event handler; allows multiple events and functions.

    var username = document.getElementbyId("username");
    username.addEventListener("blur", checkName, false);

    The boolean at the end indicates if events should be captured; it is usually set to false.

    The triggered action is often written as an “anonymous” function in simple scripts:

    var username = document.getElementbyId("username");
    username.addEventListener("blur", function() {
        // actions taken when the event is triggered
    })

I’ll be covering events in far greater detail in future articles; for now, there are a few things to note:

Not All Events Are Equal

It’s important to understand that not all events can be handled in the same way: some events, like scroll and resize, are fired multiple times during the event, and need to be treated carefully if you want your script to be efficient. This is also true with events that may appear inncuous at first, like input. Scripts can start to stagger and perform poorly as they attempt respond to the frequently-fired input events of elements like the range slider.

Not Every Event is Tracked

Mutation observers do not currently track every alteration to every element: for example, there’s no set method for determining that the height of an element has changed (for example, as a container element narrows in a responsive design, reflowing the text inside it and causing the element to be longer). There are methods around this, however, as I’ll show in the next article.

Attach Events to Appropriate Elements

The existence of events like onclick makes them tempting to apply to many elements, including links. As a general rule, links should remain free from JavaScript: if you click on a link, it should go to another area of the site, or to a new anchor point. On the other hand, if you want a UI element to change something on the same page, it should usually be a <button>, to which JavaScript can be applied with equanimity.

Don’t Use JavaScript Events when CSS Will Do

JavaScript is slow and fragile compared to ; in general, CSS should be used whenever possible as an alternative to complex scripts. However, CSS has a limited range of interactivity: it does very well with :hover (which also covers touch events in many circumstances), and can cover click in some cases with :target. CSS animations will also automatically run on load, and there are CSS states that you can trigger based on elements like radio buttons, but anything more complex is usually best left to JavaScript.

Photograph by Thomas Hawk, used under a Creative Commons Attribution-NonCommercial 2.0 Generic license

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.