3.7 Events
Hello
Zen and the art of Coding
Please email hello@zenandtheartofcoding.info for a password

Events

📚 Table of Contents
DOM
HTML Events
JS DOM Methods
JS Event Listeners

DOM

  • before we get into events we have to talk about the DOM real quick
  • the DOM (Document Object Model) is basically how a computer interprets HTML code
  • when a browser reads HTML code, it creates a tree out of all of these HTML elements (the elements on the tree are called nodes). that tree is the DOM
  • what is cool is that the DOM is actually an interface for manipulating and controlling the HTML elements (or nodes), you can do this with JS (and other programming languages too)

HTML Events

  • I thought about defining this in the HTML chapter but it really makes more sense here
  • events are "things that happn to HTML elements". thats a little vague but thats bc it can be something automatic like when the browser finishes loading a picture to when a user actively clicks a button
  • there are a a lot of these and they can get broken down into types:
    • window events, form events, keyboard events, mouse events, drag, media and misc events
    • they all start with "on" and you can check them out here (opens in a new tab)
    • tbh a lot of these aren't really used anymore but a couple are used a lot; like onclick
    • to make things happen when a user clicks something on your web page or app UI, you use onclick the same as other HTML attributes
    <button onclick="alert('This alert was triggered by an event! 😎')">
      Click me!
    </button>
    • give it a shot if you want to play with it, paste that into the <body></body> of your index.html and click the button
    • so you add the onclick attribute and inside the quotes you can write some JS. alert() is a built-in JS function. it can get very messy very quickly writing JS directly in the HTML so you will usually (hopefully) see onclick call a JS function and have the function defined somewhere else (like over in script.js)
  • this method is usually called inline for events

note:

  • inline HTML events are also pretty much how you handle events React. for near future context, the rest of this page is only for vanilla JavaScript and understanding how this all works. React abstracts DOM manipulation and really makes things a lot cleaner and easier. most fancy coding tools do just that, try to make your life easier
  • but totally skipping the rest of this page would also be a huge mistake. in addition to knowing what you are actually doing in React, its good to know you don't need a fancy framework or library and sometimes you have to make shit work outside of React

JS DOM Methods

  • there are a ton of built-in methods (JS functions) for controlling elements of the DOM. check them out here (opens in a new tab)

  • there really are only a couple you will see a lot though:

    • getElementById() is a big one.

      • the way it works is by grabbing the id attribute (which are unique) on an HTML element.
      • set the id in the HTML:
      index.html
      <p id="spidey">The amazing Spider-Man</p>
      • then you can target the HTML element by the id with JS and do things like change the color or actual text, etc
      script.js
      // change to blue
      document.getElementById("spidey").style.color = "blue";
       
      // change the text
      document.getElementById("spidey").innerHTML = "Spidey, Spin & Ghost";
      • innerHTML is a property you can use on DOM methods to replace the contents of an HTML element. pretty tight right?
      • for a little context, changing colors is fun but also maybe more common than you think. a good example is when when you are doing some password validation, if the user inputs an incorrect password you might want to display a message in red
      • another real life example for getElementById() would be maybe you just created a pop up and the user should be able to X it out, and when that user clicks an X icon the whole pop-up should close. the way you would achieve this is by hiding the pop-up like this:
      document.getElementById("popup").style.display = "none";
    • if for some reason you need to target an element that doesn't have an id, you can use querySelector()

      • this one is a little less common but he will see you in the wild
      • querySelector() Will target in the first element on the DOM tree that you were looking for
      // grab the first p tag element on the DOM
      document.querySelector("p");
    • if you need to find all of the p tags and not just the first one you can use querySelectorAll()

      // grab all of the p tag elements on the DOM
      document.querySelectorAll("p");
    • you can also target by class and id the exact same way you do with CSS with these

      // grab elements by class
      document.querySelector("p.superhero").style.display = "bold";
       
      // grab elements by id
      document.querySelector("#spidey").style.color = "blue";

JS Event Listeners

  • ok so, adding the HTML events like onclick (using inline) to your elements is actualy only one way to make the HTML elements reactive

  • with vanilla JavaScript (no framework or library like React), it is considered to be much cleaner to use event listeners. also, sometimes you are manipulating HTML that you don't have full control over and to use event listeners you only need the id of the element

  • like the name suggests, an event listener is a JavaScript tool that allows you to wait for events (like clicks, mouse movements, key presses, etc.) and then execute code in response to those events

  • the way you use it is by grabbing an element, using the addEventListener() function and inside the function you define the type of event you are listening for and the write your own JavaScript function for what you want to do:
    element.addEventListener(event, function)

    document.getElementById("aButton").addEventListener("click", function () {
      alert("a button was clicked!");
    });
    • quick note on the JS function you provide: its common to keep that function "anonymous", which is another way to say it doesn't have a name
    • also to make things a little cleaner an easier to read, it's usually good practice to set the element to a variable
    const aBtn = document.getElementById("aButton");
     
    aBtn.addEventListener("click", function () {
      alert("a button was clicked!");
    });
  • note: you can add as many event handlers to the same element as you want

Event Propagation: Bubbling and Capturing

  • I would call this next section advanced. you usually don't have to worry about this but I still wanted to include it

  • event propagation is a way of defining the element order when an event occurs

    • when you have nested HTML elements (which is super common, think about putting elements in div tags), sometimes you'll want to control which element's event happens first
  • bubbling is when the inner most element's event is handled first and then bubbles up to the outer elements

  • capturing is the opposite and when the outer most element's event is handled first and goes down to the target element

  • the way you control this is by using a third optional parameter, called useCapture on the addEventListener() function

    • syntax: element.addEventListener(event, function, useCapture).
    const aBtn = document.getElementById("aButton");
     
    aBtn.addEventListener(
      "click",
      function () {
        alert("a button was clicked!");
      },
      true
    );
    • useCapture is a boolean value, which means you send it to true or false
    • if you don't define it, it defaults to false which uses bubbling propagation. setting it to true uses capturing propagation
  • i.e.:

<!-- Nested elements -->
<div id="outerDiv">
  <button id="innerButton">Click Me</button>
</div>
const outerDiv = document.getElementById("outerDiv");
const innerButton = document.getElementById("innerButton");
 
// Capturing example
outerDiv.addEventListener(
  "click",
  function () {
    alert("Div (capturing phase)");
  },
  true
); // Capturing enabled
 
// Bubbling example
innerButton.addEventListener(
  "click",
  function () {
    alert("Button (bubbling phase)");
  },
  false
); // Bubbling is the default