CSE 154
Lecture 8: JavaScript and the Document
Object Model (DOM)
/
Today's Agenda
Reminder: Homework 2 due tonight
Creative Project 3
Cloud 9
Modular JavaScript
HTML Form elements
The Document Object Model (DOM) and DOM elements
/
Getting on your Cloud 9 team
We will be switching to using Cloud9 over the next week because it will be easier to do
the server-side programming later in the term. We want you to get used to
programming in it sooner rather than later.
You will an email from your TA through Cloud9 with a link to accept an invitation to join the "CSE 154 Spring
2018 - A_ and A_ " team. Accept this invitation and setup an account by doing the following:
1. Click the link in the email from Cloud9 inviting you
2. Click 'Create new account' on the Welcome to Cloud9 Teams! page
3. Type your name in the 'Your Name' field and click 'Next'
4. Pick a username, type it in the 'username' field, and click 'Next'
5. Make sure to select 'Student' when it asks 'What kind of developer are you?', and 'Coursework' for 'How
will you use Cloud9?' (otherwise, there will be charges if Student is not selected!). Then, click 'Next'
6. Confirm your details and click 'Next'
7. Do the captcha if it asks you to, and click 'Create account'
8. Click 'Join team' when it says 'You have been invited to join team cse154'
9. Make sure to set your password in the email you will soon receive from Cloud9.
10. Click the slide below to learn howo to clone the workspace.
/
Cloning your workspace
1. Click on the link to your new team subscription on the le hand side ("CSE 154 Spring 2018 - A_ and A_"
where the _ are filled in).
2. Look for the docbrick workspace. Click on the black Clone button.
3. Give your workspace a name, a description and make sure the team and workspace settings are still
correct!
4. Once you hit the button, you'll go into the Cloud 9 workspace (it takes a little while to set up.
IMPORTANT - Make your Workspace Private.
1. Go back to your dashboard (Select Cloud9->Dashboard)
2. Click on the big white square for your workspace, anywhere EXCEPT the the clone or open buttons.
3. Click on the gear icon
4. Change your workspace visibility to private and save.
If you do not do that last step you can not guarantee that you work is not plagiarized.
/
JavaScript Review not Review
/
JavaScript Review From Lecture 7
Examples of some "less-intuitive" evaluations (from here):
2 < 1 < 2; // true
0 + "1" + 2; // "012"
[] + []; // ""
"1" / null; // Infinity
0.1 + 0.2 == 0.3; // false
/
Defining Functions
function name(params) {
statement;
statement;
...
statement;
}
JS (template)
function myFunction() {
[Link]("Hello!");
alert("Your browser says hi!");
}
JS (example)
The above could be the contents of [Link] linked to our HTML page
Statements placed into functions can be evaluated in response to user events
Practice: fixErrors2 , containsTwice , functionMystery1 , sumUpTo ,
veryBestSong
/
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 so ware 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 mentioned the keyword let as a way to declare a variable in the current scope
(i.e. between {}'s for instance).
function sayHello(name) {
let output = "Hello " + name; // output is local to sayHello
[Link](output);
}
JS
/
Example 1: Globals
Globals are variables or symbols 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 symbols 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; // deiz would not be able to be set here.
}
incr(4);
incr(2);
[Link](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);
[Link](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() {
[Link]("varTest");
var x = 1;
if (x === 1) {
var x = 2; // same variable!
[Link](x); // 2
}
[Link](x); // 2
}
function letTest() {
[Link]("letTest");
let x = 1;
if (x === 1) {
let x = 2; // different variable
[Link](x); // 2
}
[Link](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);
[Link](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
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);
[Link](count);
})();
/
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
* Stuff about my file
*/
(function() {
// phew! your code goes here
})();
JS
/
Take Aways
Scoping is ... confusing
You might not "get" it until you run into a bug
Localize scope
Use let vs var
Use the module pattern to elimiate global variables
/
Summary of Java vs. JS vs. Python
Java JS Python
Compiled vs. Compiled Interpreted Interpreted
Interpreted
Typing Strong Loose Loose
Variable Must be declared Does not need to be Does not need to be
Declaration before use declared before use declared before use
Key Construct Classes (OOP) Function Function
/
Back to HTML (Briefly!)
/
<button>
<button id="my-btn">Click me!</button>
HTML
Click me!
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 [Link]
let element = [Link]("id");
JS
[Link] 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
[Link] = handleFunction;
function handleFunction() {
// event handler code
};
JS (onclick template)
// (alternative) attaching an "anonymous" function
[Link] = function() { // attaching onclick function
// event handler code
};
JS (onclick template)
JavaScript functions can be set as event handlers
When you interact with the element, the function will execute
onclick is just one of many event HTML attributes we'll use
/
Putting it back together
<img id="pokeball" src="images/[Link]" alt="a pokeball" />
<button id="demo-btn">Click me!</button>
HTML
let demoButton = [Link]("demo-btn");
[Link] = changeImg;
function changeImage() {
let pokeballImg = [Link]("pokeball");
[Link] = "images/[Link]";
}
JS
Click me!
output
/
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
/
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 div
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
/
How to get DOM elements in JS
1. Ask for them by id: [Link](...)
2. Query for them with CSS style selectors:
[Link](...)
[Link](...)
3. Make new ones! [Link](...)
/
Example: getting a DOM element in JS
<p id="october"></p>
HTML
let pTag = [Link]("october");
JS
/
What's inside a DOM object?
For starters, the HTML attributes. This HTML:
<img src="images/[Link]" alt="A fantastic puppy photo"/>
HTML
Has a DOM object (let's call it puppyImg ) with these two properties:
[Link] -- set by the browser to images/[Link]
[Link] -- set by the browser to "A fantastic puppy photo"
/
Accessing Properties of a DOM object
(Example)
<p>See our <a href="[Link]" id="saleslink">Sales</a> today!</p>
<img id="icon" src="images/[Link]" alt="Borat" />
<caption class="photo user-upload">Beauty.</caption>
HTML
let icon = [Link]("icon");
let theLink = [Link]("saleslink");
let caption = [Link]("caption");
JS
Property Description Example
tagName element's HTML tag [Link] is "IMG"
className CSS classes of element [Link] is "photo user-upload"
src URL target of an image [Link] is "images/[Link]"
href URL target of a link [Link] is "[Link]"
/
The innerHTML property
All DOM elements have a property called innerHTML that has the contents of the
HTML tag as a string:
<ul id="dr-seuss">
<li>Thing 1</li>
<li>Thing 2</li>
</ul>
HTML
let elm = [Link]("dr-seuss");
// [Link] : "\n <li>Thing 1</li>\n <li>Thing 2</li>\n"
JS
/
Example using the innerHTML Property
<button id="button">Click me!</button>
<span id="output">Hello </span>
HTML
[Link] = function () {
[Link]("output").onclick = addText;
}
function addText() {
let span = [Link]("output");
[Link] += " ... goodbye";
}
JS
Click me! Hello
output
Can change the text inside most elements by setting the innerHTML property
/
Abuse of innerHTML
// bad code quality! Hard to maintain! Prone to bugs!
let paragraph = [Link]("welcome");
[Link] = "<p>text and <a href=\"[Link]\">link</a>";
JS
innerHTML can inject arbitrary HTML content into page
However, this is prone to bugs and errors and is considered poor style
We do not want you using innerHTML to inject HTML tags; inject plain text only
Soon, we'll see a better way to inject content with HTML tags in it
/
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
/
Modifying DOM Elements (Example)
<a id="fb-link" href="[Link]
HTML
Before the JavaScript runs, we'd see:
Facebook
And a er we run this Javascript:
let link = [Link]("fb-link");
[Link] = "MySpace is back in a really big way."
JS
We'd see:
MySpace is back in a really big way.
/
Putting it together
/
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
Use the JS and DOM to attach and execute all JavaScript event handlers
/
But when does my code run?
<html>
<head>
<script src="[Link]" type="text/javascript"></script>
</head>
<body> ... </body>
</html>
HTML
let x = 3;
function f(n) { return n + 1; }
function g(n) { return n - 1; }
x = f(x);
[Link] -- JavaScript
Your file's JS code runs the moment the browser loads the script tag
Any variables are declared immediately
Any functions are declared but not called, unless your global code explicitly calls them
Important! At this point in time, the browser has not yet read your page's body
None of the DOM objects for tags on the page have been created yet
/
A failed attempt at being unobtrusive
<html>
<head>
<script src="[Link]" type="text/javascript"></script>
</head>
<body>
<div><button <em>id="ok"</em>>OK</button></div>
(... more html ...)
HTML
let btn = [Link]("ok");
[Link] = okayClick; // this is bad: btn is null at this point
[Link] -- JavaScript
Problem: global JS code runs the moment the script is loaded
Script in head is processed before page's body has loaded
No elements are available yet or can be accessed yet via the DOM
We need a way to attach the handler a er the page has loaded...
/
The [Link] event
function functionName() {
// put code to initialize the page here
}
// instruct window to run the function when the page has loaded:
[Link] = functionName;
JS (template)
There is a global event called [Link] event that happens once everything in
the page has been loaded
If you attach a function as a handler for [Link] , it will run at that time
/
How an event is handled
<button id="ok">OK</button> <!-- (1) -->
HTML
// called when page loads; sets up event handlers
function pageLoad() {
let ok = [Link]("ok"); // (3)
[Link] = okayClick;
}
function okayClick() {
alert("booyah"); // (4)
}
[Link] = pageLoad; // (2)
JS
OK
/
JS Skeleton
Download [Link] (and rename it) as a starting point
<!-- in the <head> block -->
<script src="path/to/javascript/[Link]" type="text/javascrpt"></script>
HTML
(function() {
[Link] = function() {
// phew! your code goes here
};
})();
JS
/
Common Unobtrusive JS Errors
event names are all lowercase, not capitalized like most variables
// [Link] = pageLoad; // WRONG!!!
[Link] = pageLoad; // right!
JS
you shouldn't write () when attaching the handler
(if you do, it calls the function immediately, rather than setting it up to be called later)
// [Link] = okayClick(); // WRONG!!!
[Link] = okayClick; // right!
JS
The JSLint checker will catch this mistake
Related: can't directly call functions like alert ; must enclose in your own function
// [Link] = alert("booyah"); //WRONG!!!
[Link] = okayClick; // right
function okayClick() { alert("booyah"); }
JS
/
Anonymous function example
[Link] = function() {
let ok = [Link]("ok");
[Link] = okayClick;
};
function okayClick() {
alert("booyah");
}
JS
OK
or, the more concise, but perhaps harder to read:
[Link] = function() {
[Link]("ok").onclick = function() {
alert("booyah");
};
};
/
Unobtrusive styling
function okayClick() {
[Link] = "red"; // <-- bad style
[Link] = "highlighted"; // <-- better style
}
HTML
.highlighted { color: red; }
CSS
Well-written JavaScript code should contain as little CSS as possible
Use JS to set CSS classes/IDs on elements
Define the styles of those classes/IDs in your CSS file
/
Wat?
This is worth 3 minutes of your viewing pleasure.