Lambda School: Full Stack – Unit 2, Sprint 5: DOM II

DOM II builds on the previous lesson and introduces us to events and event listeners, which bring interactivity and dynamism to web pages and applications. This is the lesson in which manipulating the DOM directly, instead of updating our HTML, made sense to me. With the previous lesson, there was nothing that I’d rather have done through JavaScript that couldn’t have been done more simply with HTML. Now, with the introduction of user-triggered events, I began to see how powerful DOM manipulation could be.

Sprint 2

Modifying a web page, adding features and explicitly reacting to user input opened up a path to application development that was a different level than just drafting static landing pages with CSS hover effects. Button clicks, drag-and-drop, using the mouse wheel, responding to keystrokes – all of this, and more, became possible with event listeners.

Events are users interactions with a website. There are dozens of different events available to make websites interactive, and the browser is always tracking them, waiting for input. When an event happens on a page, its called a trigger.

As per the Lambda text:

Now that we know what an event is and we know the browser is always tracking them, we need to be able to listen for specific events on specific elements. Did a user click that button? Did a users mouse hover over an element? Was there text entered into the input field? There are dozens of events an element can listen for. And when one of those events happens on that element, we can do something about it. This is called an event listener. We put an event listener on an element and give it a callback. When that event is triggered on the element, the callback is run.

Event Listeners and Handlers

Specific HTML elements can be selected to listen for specific events and then fire a callback when that event is triggered. This is called an event listener.

.addEventListener: Once an element has been selected, the .addEventListener method can be added to it. .addEventListener takes two arguments. The first is the event to listen for, and the second is the callback to launch when that event is triggered.

element.addEventListener('click', callback);

There are many events across many categories available for the browser to respond to. Mouse events are the most common – especially those triggered by the “click” event, but network events, focus events, form events, keyboard events, media events, progress events, and other categories are available, each with their own selection of events to choose from. There are even (currently) niche categories like VR (virtual reality) events!

Multiple event listeners can be chained to a single element, so its possible to have something like a button listen for a mouse click, keypress, hover and more at the same time. Each needs its own .addEventListener and callback, however.

The callback, or event handler, takes a single argument, called an event object. Its a JavaScript Object and contains details about the event and element that it was triggered from.

element.addEventListener('click', (event) => {//Event Handler});

.target

A key property of the event object is .target. It contains all of the information about the DOM node that an event was triggered on. .target has many of the same properties as a regular DOM node: .children, .parent, .style, even deprecated properties like .innerText. These properties can be used to manipulate the element or its relatives in virtually any way.

A simple example is changing an element’s background color:

element.addEventListener('click', (event) => { 
  event.target.style.backgroundColor = 'red'; });

Some events that are listened for include additional information that can be listened for, such as a code indicating a specific keypress. I’ve seen this used in online drum kit applications – an event listener waits for a keypress, sends the ASCII code or escape character for that key to the callback, and the callback plays a specific sound based on the key that was pressed.

2019.09.03 04

Event Propagation

Event propagation is a process in which an even is triggered on an object and then duplicated on every linked object going up the object’s branch until it reaches the uppermost level of the DOM. Basically, if an event is triggered on a child element, it is also triggered on every parent element, all the way up to the <body>. The event has to be the same for each of them for this to occur.

An example is having a <button> inside of a <div> which is in another <div>. If each of these has a trigger, like “click” then clicking on the <button> will trigger a click for the parent <div> and the grandparent <div>, because they’re all overlapping on the same space, or branch of the tree. This can be a dangerous behavior, resulting in unwanted interactions, although in some cases it can be a feature.

We can stop event propagation from occurring with a method called .stopPropagation(). If called in an event handler, it stops the event from bubbling further up the chain than the originally triggered object.

const eventHandler = (event) => { event.stopPropagation() };

.preventDefault

I’m too tired to put this into my own words right now, so as per the Lambda text:

Some elements have a native default reaction to certain events. For example, form elements will refresh the page on submit. .preventDefault is a method on the event object and it will stop an HTML element from reacting in its default way. This will be used less than .stopPropagation, but it is important to know about.

Although I didn’t make much use of .preventDefault when it was introduced, it has come into play since starting the Single Page Applications unit at Lambda. We’ve used it to stop hyperlinks from loading other pages, keeping the browser from sending a network request to the server for a new page and instead rendering part of a page via a component, causing only a partial refresh. I’m sure there are other uses for it, but that’s been the most common use for me, so far.

Leave a comment