Reminder: Homework 2 due tonight
Creative Project 3
Cloud 9
Modular JavaScript
HTML Form elements
The Document Object Model (DOM) and DOM elements
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:
IMPORTANT - Make your Workspace Private.
If you do not do that last step you can not guarantee that you work is not plagiarized.
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
function name(params) {
statement;
statement;
...
statement;
}
JS (template)
function myFunction() {
console.log("Hello!");
alert("Your browser says hi!");
}
JS (example)
The above could be the 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
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 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
console.log(output);
}
JS
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);
console.log(count);
JS
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
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
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
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.
(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
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);
})();
"use strict";
...your code...
JS
Writing "use strict";
at the very top of your JS file turns
on strict syntax checking:
You should always turn on strict mode for your code in this class!
/*
* name
* Stuff about my file
*/
(function() {
// phew! your code goes here
})();
JS
let
vs var
Java | JS | Python | |
---|---|---|---|
Compiled vs. Interpreted | Compiled | Interpreted | Interpreted |
Typing | Strong | Loose | Loose |
Variable Declaration | Must be declared before use | Does not need to be declared before use | Does not need to be declared before use |
Key Construct | Classes (OOP) | Function | Function |
<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:
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
// attaching a named function
element.onclick = handleFunction;
function handleFunction() {
// event handler code
};
JS (onclick template)
// (alternative) attaching an "anonymous" function
element.onclick = 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
<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.onclick = changeImg;
function changeImage() {
let pokeballImg = document.getElementById("pokeball");
pokeballImg.src = "images/mystery.gif";
}
JS
output
A tree-shaped structure built out of all of the HTML elements in a page, accessible via JavaScript
<html>
<head>
<title> ... </title>
</head>
<body>
<h1> ... </h1>
<div>
<p> ... </p>
</div>
</body>
</html>
HTML
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
We can change state
div
We can change styles
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 |
document.getElementyById(...)
document.querySelector(...)
document.querySelectorAll(...)
document.createElement(...)
<p id="october"></p>
HTML
let pTag = document.getElementById("october");
JS
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"
<p>See our <a href="sale.html" id="saleslink">Sales</a> today!</p>
<img id="icon" src="images/borat.jpg" alt="Borat" />
<caption class="photo user-upload">Beauty.</caption>
HTML
let icon = document.getElementById("icon");
let theLink = document.getElementById("saleslink");
let caption = document.querySelector("caption");
JS
Property | Description | Example |
---|---|---|
tagName
|
element's HTML tag |
icon.tagName is "IMG"
|
className
|
CSS classes of element |
caption.className is "photo user-upload"
|
src
|
URL target of an image |
icon.src is "images/borat.jpg"
|
href |
URL target of a link |
theLink.href is "sale.html"
|
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 = document.getElementById("dr-seuss");
// elm.innerHTML : "\n <li>Thing 1</li>\n <li>Thing 2</li>\n"
JS
innerHTML
Property
Hello
HTML
window.onload = function () {
document.getElementById("output").onclick = addText;
}
function addText() {
let span = document.getElementById("output");
span.innerHTML += " ... goodbye";
}
JS
output
Can change the text inside most elements by setting the innerHTML
property
innerHTML
// bad code quality! Hard to maintain! Prone to bugs!
let paragraph = document.getElementById("welcome");
paragraph.innerHTML = "<p>text and <a href=\"page.html\">link</a>";
JS
innerHTML
can inject arbitrary HTML content into page
However, this is prone to bugs and errors and is considered poor style
innerHTML
to inject HTML tags;
inject plain text onlySet 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
<a id="fb-link" href="http://www.facebook.com">Facebook</a>
HTML
Before the JavaScript runs, we'd see:
And after we run this Javascript:
let link = document.getElementById("fb-link");
link.innerHTML = "MySpace is back in a really big way."
JS
We'd see:
Recall our goal was to keep our web site code "modular" and separated into 3 major categories:
What does this mean?
<script>
tags<html>
<head>
<script src="myfile.js" 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);
myfile.js
-- JavaScript
Your file's JS code runs the moment the browser loads the script
tag
Important! At this point in time, the browser has not yet read your page's body
<html>
<head>
<script src="myfile.js" type="text/javascript"></script>
</head>
<body>
<div><button id="ok">OK</button></div>
(... more html ...)
HTML
let btn = document.getElementById("ok");
btn.onclick = okayClick; // this is bad: btn is null at this point
myfile.js
-- 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 after the page has loaded...
window.onload
eventfunction functionName() {
// put code to initialize the page here
}
// instruct window to run the function when the page has loaded:
window.onload = functionName;
JS (template)
There is a global event called window.onload
event that happens once everything in the page has been loaded
If you attach a function as a handler for window.onload
, it will run at
that time
<button id="ok">OK</button> <!-- (1) -->
HTML
// called when page loads; sets up event handlers
function pageLoad() {
let ok = document.getElementById("ok"); // (3)
ok.onclick = okayClick;
}
function okayClick() {
alert("booyah"); // (4)
}
window.onload = pageLoad; // (2)
JS
Download template.js (and rename it) as a starting point
HTML
(function() {
window.onload = function() {
// phew! your code goes here
};
})();
JS
event names are all lowercase, not capitalized like most variables
// window.onLoad = pageLoad; // WRONG!!!
window.onload = 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)
// ok.onclick = okayClick(); // WRONG!!!
ok.onclick = okayClick; // right!
JS
The JSLint checker will catch this mistake
Related: can't directly call functions like alert
;
must enclose in your own function
// ok.onclick = alert("booyah"); //WRONG!!!
ok.onclick = okayClick; // right
function okayClick() { alert("booyah"); }
JS
window.onload = function() {
let ok = document.getElementById("ok");
ok.onclick = okayClick;
};
function okayClick() {
alert("booyah");
}
JS
or, the more concise, but perhaps harder to read:
window.onload = function() {
document.getElementById("ok").onclick = function() {
alert("booyah");
};
};
function okayClick() {
this.style.color = "red"; // <-- bad style
this.className = "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