CSE 154

Section 4: Introduction to JavaScript

Section Goals

By the end of this section, you should be able to:

  • Quick review on Flexbox
  • Be able to write a JavaScript file and link it to HTML
  • Be able to write JavaScript functions which update a page's content/style

QuickCheck!

Reminder

HW1 is due tomorrow by 11pm. Make sure to add/commit/push and hit the turn in button!

CP1 Assignment Feedback

When we finish grading an assignment, you will get an email with a link to the feedback. The email will contain two links: One goes to the scoresheet with your total score and any comments we have left for the criteria, and one goes to the annotated code, where we mark lines of your code up with feedback and give overall comments.

It is strongly recommended that you read feedback when it is released so that you can implement it into your current assignments, as we point out not only deductions, but things that could be deductions in the future, as well as general advice. We work hard on giving detailed feedback, so please do read it!

Warm up to JS syntax!

Exercise 1: cRaZyCaPs

Write a function named crazyCaps that accepts a string as a parameter and returns a new string with its capitalization altered such that the characters at even indexes are all in lowercase and odd indexes are all in uppercase.

For example, if a variable str stores "Hey!! THERE!", the call of crazyCaps(str) should return "hEy!! tHeRe!".

Exercise 1: Solution


                function crazyCaps(str) {
                  let result = "";
                  for (let i = 0; i < str.length; i++) {
                    if (i % 2 === 0) {
                      result += str[i].toLowerCase();
                    } else {
                      result += str[i].toUpperCase();
                    }
                  }
                  return result;
                }
                

JS

Event-Driven Programming

event-driven programming

Unlike Java programs, JS programs have no main; they respond to user actions called events

Event-Driven Programming: writing programs driven by user events

Mouse Event Demo

?

click

mouseenter

mouseleave

mouseover

mousedown

mouseup

dblclick

Event Demo

Subtle distinctions (non-testable material):

  • click requires mouseup and mousedown to occur on the same element.
  • mouseover will trigger again on child elements, unlike mouseenter

Accessing an Element: document.getElementById

let element = document.getElementById("id");
  

JS

document.getElementById returns the DOM object for an element with a given id (note that you omit the # when giving an id)

Refreshing our Selector Skills

Groupizer DOM Tree

What CSS selector would you use to select the unordered list on this page?

What CSS selector would you use to select the inputs in that list?

Using Selectors in JS

Methods in document and other DOM objects:

Name Description
querySelector(selector) returns the first element that would be matched by the given CSS selector string
querySelectorAll(selector) returns an array of all elements that would be matched by the given CSS selector string

Summarize: How to get DOM elements in JS

  1. Ask for them by id: document.getElementyById(...)
  2. Query for them with CSS style selectors:
    • document.querySelector(...)
    • document.querySelectorAll(...)

Common querySelectorAll issues

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

// get all buttons with a class of "control"
let gameButtons = document.querySelectorAll("control");
let gameButtons = document.querySelectorAll(".control");

JS

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

// set all buttons with a class of "control" to have red text
document.querySelectorAll(".gamebutton").classList.add("hidden");
let gameButtons = document.querySelectorAll(".gamebutton");
for (let i = 0; i < gameButtons.length; i++) {
  gameButtons[i].classList.add("hidden");
}

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!)

Getting the first element of a certain type

Use querySelector to highlight the first paragraph in the document:

<body>
  <p>This is the first paragraph</p>
  <p>This is the second paragraph</p>
  <p>You get the idea...</p>
</body>

HTML

// get the first DOM object that is a <p>
let para = document.querySelector("p");
para.classList.add("highlighted");

JS

Handy Shortcut Functions

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

function id(idName) {
  return document.getElementById(idName);
}

function qs(selector) { // less common, but you may find it helpful
  return document.querySelector(selector);
}

function qsa(selector) {
  return document.querySelectorAll(selector);
}

JS

We will be using these in examples! Here is the full template with documentation.

Handling Events

// attaching a named function
element.addEventListener("click", handleFunction);

function handleFunction() { // attaching onclick function
  // event handler code
}

JS (template)

JavaScript functions can be set as event handlers

When you interact with the element, the function will execute

click is just one of many event types we'll use

Back to HTML with Buttons: <button>

<button id="my-btn">Click me!</button>
          

HTML

output

Button's text appears inside tag; can also contain images

To make a responsive button or other UI control:

  1. Choose the control (e.g., button) and event (e.g., mouse click) of interest
  2. Write a JavaScript function to run when the event occurs
  3. Attach the function to the event on the control

In this example, we haven't added any JavaScript! So there's no program to know how to handle click events :( Let's fix that!

click Event Handler: an Example

<img id="pokeball" src="images/pokeball.jpg" alt="a pokeball" />
<button id="demo-btn">Click me!</button>

HTML

let demoButton = document.getElementById("demo-btn");
demoButton.addEventListener("click", changeImage);

function changeImage() {
  let pokeballImg = document.getElementById("pokeball");
  pokeballImg.src = "images/mystery.gif";
}

JS

a pokeball

output

Exercise 2: Goofy Scripts

Let's write some toy scripts that we can use to mess with the internet!

  • Write a function that selects all images on the webpage and sets their src attribute to https://i.giphy.com/media/IfuEfxTfeorNS/giphy.webp
  • Write a function that selects all paragraphs on the webpage and capitalizes their text. DOM objects have a textContent property that you can access to get the text in the element, or set to change the text.

Hint: Use document.querySelectorAll to get an array of DOM objects.

Hint: Strings have a toUpperCase function that returns the string in all caps.

To test your function, paste it into the console on a webpage (like this or this) and then call the function in the console. It can be fun to do stuff like this on random websites (and it is similar to what browser exentsions do).

Img Script Solution

P Tag Script Solution

Bonus Exercise 3: What's Your Color?

We've provided an HTML file colorifyme.html and a start to a JavaScript file colorify.js that it links to. Download both files and fill in the "TODO" comments of colorify.js so that when the web page's "colorify" button is clicked, it randomly decides the color of the page background. That is, it should choose a random hex value for the background between #000000 and #FFFFFF. In addition, it should replace any text in the heading tag that has the ID "my-color" with the text, "Your color is RANDOMCOLOR!", (where RANDOMCOLOR is the hex value randomly-generated for the background).

A runnable solution is located here (don't peek at the solution code!)

Bonus Exercise 3: Solution

"use strict";
(function() {
  const HEX_DIGITS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                      "A", "B", "C", "D", "E", "F"];
  const HEX_LENGTH = 6; // Number of hexidecimal digits in a color code
  window.addEventListener("load", init);

  function init() {
    let colorBtn = document.getElementById("colorify");
    colorBtn.addEventListener("click", changeBackgroundColor);
  }

  function changeBackgroundColor() {
    let randomColor = "#";
    for (let i = 0; i < HEX_LENGTH; i++) {
      randomColor += HEX_DIGITS[Math.floor(Math.random() * HEX_DIGITS.length)];
    }
    document.body.style.backgroundColor = randomColor;
    document.getElementById("my-color").textContent = "Your color is " + randomColor + "!";
  }
})();

JS

Bonus Exercise

Try this on your own if you'd like more practice with JavaScript

Exercise 4: Mass Conversion

Create the file conversions.js which is referenced by conversions.html. Write a function convert() in conversions.js that takes the value in the text input and converts it from either kilograms (kg) to pounds (lb) or from pounds to kilograms, depending on the value selected in the dropdown box.

The result should be displayed in the empty span with the id of #answer.

The conversion factor from pounds to kilograms is 0.45359237, and the conversion factor from kilograms to pounds is 2.20462262.

You should edit the HTML file conversions.html to add id's to the elements as necessary and you may assume valid input. A runnable version of the solution can be found here (don't peek at the solution code!)

Exercise 4: Solution

              (function() {
  "use strict";
  window.addEventListener("load", init);

  function init() {
    let calcButton = document.getElementById("calculate");
    calcButton.addEventListener("click", convert);
  }

  function convert() {
    let input = document.getElementById("input");
    let value = parseInt(input.value);

    let conversion = document.getElementById("convert");
    if (conversion.value == "kgtopounds") {
      value *= 2.20462262;
    } else {
      value *= 0.45359237;
    }

    let answer = document.getElementById("answer");
    answer.innerHTML = value;
  }
})();