CSE 154

Lecture 7: JS - Document Object Model (DOM) and UI Events

Today's Agenda

  • Administrivia:
    • Reminder: Homework 2 due tonight
    • Creative Project 2 out
    • Exploration Session on CSS Animations tomorrow!
  • JavaScript Equality
  • Modular JavaScript
  • The Document Object Model (DOM) and DOM elements
  • HTML Form (UI) Elements

Boolean Type

            let iLikeJS = true;
let ieIsGood = "IE6" > 0; // false
if ("web dev is great") { /* true */ }
if (0) { /* false */ }
if (1) { /* true */ }

JS

Any value can be used as a Boolean

  • "falsey" values: false, 0, NaN, "", null, and undefined
  • "truthy" values: anything else

Understanding what is "falsey" vs. "truthy" takes patience and practice.

When in doubt, check in the browser console!

Logical Operators

Relational: > < >= <=

Logical: && || !

Equality: == != === !==

  • Most logical operators automatically convert types. These are all true:
    • 5 < "7"
    • 42 == 42.0
    • "5.0" == 5
  • The === and !== are strict equality tests; checks both type and value: "5.0" === 5 is false. It's usually a good idea to use === instead of ==.
  • What does 154 === 154.0 evaluate to?

Helpful JavaScript equality table!

A Few Last Notes on Types in JavaScript

As you write JS programs, you may will run into some silent bugs resulting from odd typing behavior in JS. Automatic type conversion, or coersion, is a common, often perplexing, source of JS bugs (even for experienced JS programmers).

Why does it happen? JS was designed to "work" as intuitively as possible without requiring the strict types.

Why is this important to be aware of? You'll be writing programs which use variables and conditional logic. Knowing what is considered truthy/false and how types are evaluated (at a high level) can make you a much happier JS developer (some practice)

Examples of some "less-intuitive" evaluations:

2 < 1 < 2;// true

0 + "1" + 2;// "012"

0.1 + 0.2 == 0.3;// false

[] + [];// ""

"1" / null;// Infinity

This is worth 3 minutes of your viewing pleasure. (starting at 1:20)

Review: Function Syntax

function name(params) {
  statement;
  statement;
  ...
  statement;
}

JS (template)

function myFunction(name) {
  console.log("Hello " + name + "!");
  alert("Your browser says hi!");
}

JS (example)

The above could be the entire contents of example.js linked to our HTML page

Statements placed into functions can be evaluated in response to user events

Practice: fixErrors2 , containsTwice , functionMystery1 , sumUpTo , veryBestSong

See below slides for a comparison of an example JS function, Java method, and Python function.

JS Function vs. Java Method

function repeat(str, n) {
  let result = str;
  for (let i = 1; i < n; i++) {
    result += str;
  }
  return result;
}
let repeatedStr = repeat("echo...", 3); // "echo...echo...echo..."

JS (example)

public static String repeat(String str, int n) {
  String result = str;
  for (int i = 1; i < n; i++) {
    result += str;
  }
  return result;
}
// ... 
String repeatedStr = repeat("echo...", 3); // "echo...echo...echo..."

Java (example)

JS Function vs. Python Function

function repeat(str, n) {
  let result = str;
  for (let i = 1; i < n; i++) {
    result += str;
  }
  return result;
}
let repeatedStr = repeat("echo...", 3); // "echo...echo...echo..."

JS (example)

def repeat(str, n):
  result = str;
  for i in range(1, n):
    result = result + str;
  return result;

repeatedStr = repeat("echo...", 3) // "echo...echo...echo..."

Python (example)

Documenting JS Functions with JSDoc

In this class, we expect you to use the @param and @returns annotation tags in JSDoc when appropriate for the function.

The @param annotation specifies the name and type of each parameter, as well as what the purpose of that parameter is in the function.

The @returns annotation specifies the type and expected value of what is returned given the parameters and any other conditions of the function. You do not need to use any other JSDoc annotations in CSE 154.

Documenting JS with JSDoc: Templates

Here is an example of function comment skeletons as reference:

// Single-line JSDoc comment:
/** Your comment here */

JSDoc Single-Line Comment

/**
 * brief description of the function
 * @param {datatype} parameterName1 - parameter description
 * @param {datatype} parameterName2 - parameter description
 * @returns {datatype} Description of the return value
 */
function functionName(parameterName1, parameterName2) {
  ...
}

JSDoc Function Template (Multi-line)

You can find more examples in our Code Quality Guide.

Scoping

When and where are variables defined and updated in a JS program?

What was that module pattern we saw in Section yesterday?

Scoping

Remember that the scope of a variable is the region of a computer program where the variable name may be used.

Recall that it is generally better, for software maintainabilty, to localize your variables, i.e. keep their scope as limited as possible to avoid "side effects" from other parts of the program.

We've seen the keyword let used to declare a variable in the current scope (i.e. between {}'s of a function/loop/conditional statement).

function sayHello(name) {
  let output = "Hello " + name;  // output is local to sayHello
  console.log(output);
}

JS

Example 1: Globals

Globals are variables or functions that are visible throughout the entire program. They can be bad; other code and other JS files can see and modify them, sometimes unexpectedly!

Example: how many global variables/functions are introduced by this code? 3 (count, incr, and reset)

let count = 0;        // count is a global variable

function incr(n) {    // n is a parameter, local to function incr
  let diez = 10;      // diez is a local variable
  count += n;
}

function reset() {
  count = 0;          // because count is global it can be reset here
  // diez = 0;        // diez would not be able to be set here.
}

incr(4);
incr(2);
console.log(count);

JS

Example 2: Let Variables

let localizes the scope of a variable. Sometimes with interesting results. Example:

let count = 0; // this count is a global variable

function incr(n) {
  let count  = 10;    // this count is a local to incr
  count += n;
}

incr(4);
incr(2);
console.log(count);

JS

Aside: don't use var

We don't want you using var. Period. Even if you see others use it. Example:

function varTest() {
  console.log("varTest");
  var x = 1;
  if (x === 1) {
    var x = 2;          // same variable!
    console.log(x);     // 2
  }
  console.log(x);         // 2
}

function letTest() {
  console.log("letTest");
  let x = 1;
  if (x === 1) {
    let x = 2;          // different variable
    console.log(x);     // 2
  }
  console.log(x);         // 1
}

JS

Containing globals in a function

If we enclose the code all in one function, it encloses the scope of all of those symbols into that function.

Example: how many global symbols are introduced by this code? only 1 (everything)
But can we get it to 0?

function everything() {
  let count = 0;

  function incr(n) {
    count += n;
  }

  function reset() {
    count = 0;
  }

  incr(4);
  incr(2);
  console.log(count);
}

everything(); // call the function to run the code

JS

Anonymous Functions

function(parameters) {
  ... statements ...;
}

JavaScript allows you to declare anonymous functions

Quickly creates a function without giving it a name

Can be stored as a variable, attached as an event handler, etc.

The "module pattern"

(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 messed with externally

Module pattern example

Example: How many global symbols are introduced in this code?

0 global symbols!

(function() {
  let count = 0;

  function incr(n) {
      count += n;
  }

  function reset() {
      count = 0;
  }

  incr(4);
  incr(2);
  console.log(count);
})();
            

JS

JavaScript "strict" mode

"use strict";

...your code...

JS

Writing "use strict"; at the very top of your JS file turns on strict syntax checking:

  • Shows an error if you try to assign to an undeclared variable
  • Stops you from overwriting key JS system libraries
  • Forbids some unsafe or error-prone language features

You should always turn on strict mode for your code in this class!

JavaScript File Skeleton

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

  // phew! your code goes here

})();

JS

Take Aways

  • Scoping is ... confusing
  • You might not "get" it until you run into a bug, but until then don't overthink it
  • Localize scope
  • Use let vs var
  • Use the module pattern to elimiate global variables

Back to HTML (Briefly!)

Recall the <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

So how did that happen?

First you get the button from the HTML Page

To access an element you use document.getElementById

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

JS

document.getElementById returns an object for an element with a given uniqute id in the document.

Note that you omit the # when giving an id in JS

Then handle the click event

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

function handleFunction() {
  // event handler code
};

JS (click event template)


// (alternative) attaching an "anonymous" function
element.addEventListener("click", function() {
  // event handler code
});

JS (click event template)

JavaScript functions can be set as event handlers

When you interact with the element, the function will execute

Review: The DOM

A tree-shaped structure built out of all of the HTML elements in a page, accessible via JavaScript

Visualizing the tree

<html>
  <head>
    <title> ... </title>
  </head>
  <body>
    <h1> ... </h1>
    <div>
      <p> ... </p>
    </div>
  </body>
</html>

HTML

DOM

Document Object Model (DOM)

A set of JavaScript objects that represent each element on the page

Each tag in a page corresponds to a JavaScript DOM object

JS code can talk to these objects to examine elements' state

  • e.g. see whether a box is checked

We can change state

  • e.g. insert some new text into a p

We can change styles

  • e.g. make a paragraph red

The Six Global DOM Objects

Every JavaScript program can refer to the following global objects:

method description
document current HTML page and its content
history list of pages the user has visited
location URL of the current HTML page
navigator info about the web browser you are using
screen info about the screen area occupied by the browser
window the browser window

Try typing each object in your console followed by "." - your browser will try to autocomplete, and you can see what kind of information each global object has! What kind of information do you get when typing window.clientInformation?

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(...)
  3. Make new ones! document.createElement(...) (introduced soon)

What's inside a DOM object?

For starters, the HTML attributes. This HTML:

<img src="images/puppy.png" alt="A fantastic puppy photo"/>

HTML

Has a DOM object (let's call it puppyImg) with these two properties:

  • puppyImg.src -- set by the browser to images/puppy.png
  • puppyImg.alt -- set by the browser to "A fantastic puppy photo"

Changing Text with innerText

            let paragraph = document.getElementById("welcome");
paragraph.innerText = "text!";

JS

innerText should be used to replace text to a DOM element

Can't add HTML tags this way, but soon, we'll see a better way to add HTML tags to our page.

Ok, what do we do with DOM objects?

Set their properties, and the page changes in response

This is how give behavior to web pages: use JavaScript to manipulate the DOM by changing the properties of DOM elements

Unobtrusive JavaScript

Recall our goal was to keep our web site code "modular" and separated into 3 major categories:

  • content (HTML) - what is it?
  • presentation (CSS) - how does it look?
  • behavior (JavaScript) - how does it respond to user interaction?

What does this mean?

  • HTML with a link to a JavaScript file (in the module pattern) with no JavaScript code inside the <script> tags
  • Initialize your JS with a window load event handler
  • Use the JS and DOM to attach and execute all JavaScript event handlers

Exploring More UI Events with HTML Input Types

Demo!

Code introduced in lecture: HTML and JS

Documentation is included in the files if you'd like to dig a bit deeper - you'll learn how to use textarea and input boxes tomorrow!

Table of HTML Form Elements

The following is a (partial) list of HTML form elements. For more information on form elements, make sure to check W3Schools.

<input>

	            <!-- 'q' happens to be the name of Google's required paramter -->
<input type="text" name="q" value="Colbert Report" />
<input type="submit" value="Booyah!" />

HTML

Input element is used to create many UI controls (an inline element that must be self-closed

name attribute specifies name of query parameter to pass to server

type can be button, checkbox, file, hidden, password, radio, reset, submit, text, ...

value attribute specifies control's initial text

<input> Text Fields

<input type="text" size="10" maxlength="8" /> NetID <br />
<input type="password" size="16" /> Password
<input type="submit" value="Log In!" />

HTML

NetID
Password

output

input attributes: disabled, maxLength, readonly, size, value

size attribute controls onscreen width of text field

maxlength limits how many characters the user is able to type into the field

Text boxes: <textarea>

<textarea rows="4" cols="20">
Type your comments here.
</textarea>

HTML

output

Initial text is placed inside textarea tag (optional)

Required rows and cols attributes specify height/width in characters

optional readonly attribute means text cannot be modified