CSE 154

Lecture 8: More DOM/Events in JS + DOM Manipulation

Agenda

Review JavaScript Events

Intro to the Module Pattern

Intro to DOM manipulation with JS

Reminders

CP2 is out now, due next Wed, Oct 16

HW1 was due Wednesday, locks tonight

Lecture Pre-Check #3 will go out over the weekend. Check Canvas!

Questions?

JS Events

What's involved in a page event?

source.addEventListener("event", response);
function response() {
  // response behavior with possible output/document elements changed
}
  1. The source listening to the event, such as a button, dropdown, paragraph, etc.). You can also have the window as a source to listen (always for the load event, sometimes for various key events like keypress).
  2. The event listened to by a source object (e.g. click, load, mouseover, keypress).
  3. The response for the event (e.g. elements changed)

Event Handling

We can use JavaScript to attach functions to elements when an event (e.g. "click") occurs.

To do so, we need to:

  1. Identify the source element to listen for an event
  2. Indicate the event to trigger a response
  3. Specify the response function(s) to call when the event is triggered.

Once we have this information, we can use addEventListener to hook everything up!

Event handler syntax

What's the difference?

addEventListener("click", openBox);

vs.

addEventListener("click", openBox());

Event Listeners

We have two functions to manage events and response functions for elements

Use addEventListener to attach an event listener

Use removeEventListener to detach an event listener (must provide a named function reference that has been added for the listened event)

addEventListener with one event

addEventListener with multiple events

addEventListener with the Mystery Box page

removeEventListener

Removing Event Listeners: Example

function init() {
  let box = document.getElementById("box");
  box.addEventListener("mouseover", mouseOverResponse);
  box.addEventListener("dblclick", turnOffBox);
}

function mouseOverResponse() {
  console.log("You moved the mouse over a box!");
}

function turnOffBox() {
  let box = document.getElementById("box");
  box.removeEventListener("mouseover", mouseOverResponse);
  console.log("You turned off the box!");
}

JS

Running solution: box-events.html

Event Objects!

Recall that the event handler function can be attached to objects (window, DOM elements, etc.)

source.addEventListener("click", responseFunction);

function responseFunction(e) {
  // we can access the click Event object here!
}

JS

When the event occurs, an Event object is created and passed to the event listener. You can "catch" this event object as an optional parameter to get more information about the event.

Example: event-objects.html

Common Types of JavaScript Events

Name Description
load Webpage has finished loading the document
scroll User has scrolled up or down the page
click A pointing device (e.g. mouse) has been pressed and released on an element
dblclick A pointing device button is clicked twice on the same element
keydown Any key is pressed down
keyup Any key is released
mouseenter A pointing device is moved onto an element that has the attached listenere
mouseover A pointing device is moved onto the element that has the listener attached to itself or one of its children
mousemove A pointing device is moved over an element
mousedown A pointing device button is pressed on an element
mouseup A pointing device button is released over an element

We'll cover more later (you can find a full list here), but today we'll fix our click event!

Questions?

Module Pattern

Question:

What's wrong with globally accessible functions, variables, data?

The "module pattern"

"use strict";
(function() {
  statements;
})();

Wraps all of your file's code in an anonymous function that is declared and immediately called

0 global symbols will be introduced!

The variables and functions defined by your code cannot be accessed/modified externally

We'll use this pattern moving forward for all of our programs.

JavaScript File Skeleton

/**
 * Name, section, date, etc.
 * Description of program
 */
"use strict";
(function() {

  // phew! your code goes here

})();

JS

Intro to DOM Manipulation with JS

Listening to the window "load" event

You can only access document elements after the "load" event has fired.

"use strict";
(function() {
  window.addEventListener("load", init);
  // no access to the document here

  function init() {
    // we now have access to the DOM tree!
    // set up your initial document event handlers here.
  }
})();

JS

So once our DOM is ready, how do we get our page elements?

  1. Ask for them by id: document.getElementyById(...)
  2. Query for them with CSS style selectors:
    • document.querySelector(...)
    • document.querySelectorAll(...)
  3. Make new ones! document.createElement(...)

Common querySelectorAll issues

Many people forget to write . or # in front of a class or id

// get all elements with class of ".skittle"
let skittles = document.querySelectorAll("skittle");
let skittles = document.querySelectorAll(".skittle");

JS

querySelectorAll returns an array, not just a single element;
you must loop over the results

// hide all skittles
qsa(".skittle").classList.add("hidden");
let skittles = document.querySelectorAll(".skittle");
for (let i = 0; i < skittles.length; i++) {
  skittle.addEventListener("click", eatSkittle);
}

JS

Q: Can I still select a group of elements using querySelectorAll even if my CSS file doesn't have any style rule for that same group? (A: Yes!)

Handy Shortcut Functions

We will use document.getElementById and document.querySelectorAll a LOT. It's handy to declare a shortcut to help us out. You may use the following in your JS functions (these are exceptions to the rule of having description function names).

/**
 * Returns the element that has the ID attribute with the specified value.
 * @param {string} idName - element ID
 * @returns {object} DOM object associated with id.
 */
function id(idName) {
  return document.getElementById(idName);
}

/**
 * Returns the array of elements that match the given CSS selector.
 * @param {string} selector - CSS query selector
 * @returns {object[]} array of DOM objects matching the query.
 */
function qsa(selector) {
  return document.querySelectorAll(selector);
}

/**
 * Returns the first element that matches the given CSS selector.
 * @param {string} selector - CSS query selector.
 * @returns {object} The first DOM object matching the query.
 */
function qs(selector) { // less common, but you may find it helpful
  return document.querySelector(selector);
}

JS

We will start using these in examples (as well as gen for document.createElement which we'll see soon)!

A Provided JS Template

We have provided a template you can refer to for the standard JS program structure here. However, you are expected to replace the example functions and comment examples with your own (you may use the same JSDoc comments for id, qs, and qsa as is though).

Hiding/Showing Elements

How can we hide display an HTML element?

.hidden {
  display: none;
}

CSS

In JS, it's possible to modify the style properties of an element directly.

id("box-img").style.display = "none";

JS

What's wrong with that?

How can we add/remove CSS classes with JS?

Modifying the classList

You can manipulate the DOM element's classList with the following methods:

Name Description
add(classname) Adds the specified class(es) to the list of classes on this element. Any that are already in the classList are ignored.
remove(classname) Removes the specified class(es) to the list of classes from this element. Any that are already not in the classList are ignored without an error
toggle(classname) Removes a class that is in the list, adds a class that is not in the list.
contains(classname) Returns true if the class is in the the DOM element's classList, false if not.
replace(oldclass, newclass) Replaces the old class with the new class.

So how do I get started with adding interactivity to my page?

CP2 External Requirements

  • Add event listener to a source element, and respond
    • What is your source?
    • What is your event(s)?
    • What is the response behavior? Do any elements change as a result?
  • Add/remove elements in the DOM as a response to an event.

Draw tables and wireframes!