Client-Side ECMAScript/JavaScript Programming
An Introduction with Examples in HTML |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
script
element in HTML can contain
ECMAScript/JavaScript statements or can refer to a URL
that contains such statements)document
objectdocument
Object:
getElementsByTagName()
returns a list
of descendants with the given tag namegetElementById()
returns the object
with the given ID (i.e., with an id
attribute
that matches the given unique ID).
operatorgetAttribute()
and
setAttribute()
methodsload
is fired after the document has been
parsed and all content (e.g., images) has been
retrievedunload
is fired when the user leaves
the documentmousemove
, mouseover
,
mouseout
mousedown
, mouseup
,
click
, dblclick
keydown
, keyup
,
keypress
focus
, blur
change
, forminput
, input
, invalid
onevent
attribute<button id="calculate" onclick="calculateBMI();">Calculate</button>
onevent
propertydocument.getElementById("calculate").onclick = calculateBMI;
body
)
that assigns the handlers/** * A function to calculate and display the body mass index (BMI) * * @param {number} weight - The weight in pounds * @param {number} height - The height in pounds */ function calculateBMI(weight, height) { "use strict"; // ECMAScript 5 var bmi; bmi = weight / (height * height) * 703; if (bmi < 15){ bmi = 15; }else if (bmi > 60){ bmi = 60; } return bmi; }
/** * Display the BMI in an alert dialog * * This functions assumes that the document contains two text input * elements, one with an id of weight and the other with an id of height */ function displayBMI() { "use strict"; // ECMAScript 5 var bmi, height, heightField, weight, weightField; weightField = document.getElementById("weight"); heightField = document.getElementById("height"); weight = weightField.value; height = heightField.value; bmi = calculateBMI(weight, height); alert(bmi); }
<!DOCTYPE html> <html> <head> <script src="bmi.js" type="text/javascript"></script> <script src="bmi-display.js" type="text/javascript"></script> </head> <body> <label>Weight (pounds):<input type="text" id="weight" /></label><br/> <label>Height (inches):<input type="text" id="height" /></label><br/> <button onclick="displayBMI();">Calculate</button> </body> </html>
<!DOCTYPE html> <html> <head> <script src="bmi.js" type="text/javascript"></script> <script src="bmi-display.js" type="text/javascript"></script> <script src="bmi-property.js" type="text/javascript"></script> </head> <body> <label>Weight (pounds):<input type="text" id="weight" /></label><br/> <label>Height (inches):<input type="text" id="height" /></label><br/> <button id="calculate">Calculate</button> <script type="text/javascript">assignHandlers();</script> </body> </html>
this
:
this
will refer to the generatorbutton.onclick = calculator.start;
,
when start()
is invoked, this
will refer to button
NOT to calculator
button.onclick = function(){calculator.start();};
addEventListener()
method (defined
in DOM 2)shouldCapture
(if true
the
handler captures the event;
if false
the event can bubble-up
from descendants)
removeEventListener()
with the
same parameters
<!DOCTYPE html> <html> <head> <script src="bmi.js" type="text/javascript"></script> <script src="bmi-display.js" type="text/javascript"></script> <script src="bmi-register.js" type="text/javascript"></script> </head> <body> <label>Weight (pounds):<input type="text" id="weight" /></label><br/> <label>Height (inches):<input type="text" id="height" /></label><br/> <button id="calculate">Calculate</button> <script type="text/javascript">registerHandlers();</script> </body> </html>
/** * Register the event handlers */ function registerHandlers() { "use strict"; // ECMAScript 5 var calculateButton; calculateButton = document.getElementById("calculate"); /* Since the last parameter is true, the event must be generated by the button (i.e., it will not be called if the event bubbles up from a descendant) */ calculateButton.addEventListener("click", displayBMI, true); }
href
Element:
<!DOCTYPE html> <html> <head> <title>Some Courses Taught by David Bernstein</title> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" id="stylesheet" href="modern.css" /> <script type="text/javascript" src="stylesheet-change.js"></script> </head> <body> <header> <img src="bernstdh.png" /> <p> Some Courses Taught by David Bernstein </p> </header> <section> <h1>Core/Required Courses</h1> <section> <h2>CS345</h2> <h2>Software Engineering</h2> <p> Software engineering is the application of theories, methods and tools to the specification, design, creation, verification/validation, deployment, operation, and maintenance of software products. This course provides an overview of the engineering methods, processes, techniques and measurements used in the software industry. After completing this course, students will have gained some experience with these concepts should be able to explain their advantages and disadvantages, and should be able to apply them. </p> </section> </section> <section class="category"> <h1>Electives</h1> <section> <h2>CS488</h2> <h2>Computer Graphics Applications</h2> <p> This course is an introduction to 2-D and 3-D computer graphics that covers the material from the bottom up. That is, it starts with the mathematical foundations, then explores the algorithmic issues that arise when implementing those mathematical concepts, and then considers the practice of developing graphical applications (using existing libraries). </p> </section> </section> <footer> <p> Copyright (c) <a href="http://www.jmu.edu">James Madison University</a>. </p> </footer> <script type="text/javascript">registerHandlers();</script> </body> </html>
/** * Change the stylesheet */ function changeStyleSheet() { "use strict"; // ECMAScript 5 var current, file, path, pathEnd, sheet; sheet = document.getElementById("stylesheet"); current = sheet.href; pathEnd = current.lastIndexOf("/"); path = current.substring(0, pathEnd+1); file = current.substring(pathEnd+1); if (file === "traditional.css") { current = path+"modern.css"; } else { current = path+"traditional.css"; } sheet.href = current; } /** * Register the event handlers */ function registerHandlers() { "use strict"; // ECMAScript 5 document.body.addEventListener("click", changeStyleSheet, true); }
style
property-
characters but ECMAScript/JavaScript identifiers can't
so identifiers omit the -
characters and
use "camel case" (e.g., font-size
becomes fontSize
)float
) so the associated identifiers are
prefixed with css
(e.g., cssFloat
)
<!DOCTYPE html> <html> <head> <title>Some Courses Taught by David Bernstein</title> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="modern.css" /> <script type="text/javascript" src="styleattribute-change.js"></script> </head> <body> <header> <img src="bernstdh.png" /> <p> Some Courses Taught by David Bernstein </p> </header> <section> <h1>Core/Required Courses</h1> <section> <h2>CS345</h2> <h2>Software Engineering</h2> <p> Software engineering is the application of theories, methods and tools to the specification, design, creation, verification/validation, deployment, operation, and maintenance of software products. This course provides an overview of the engineering methods, processes, techniques and measurements used in the software industry. After completing this course, students will have gained some experience with these concepts should be able to explain their advantages and disadvantages, and should be able to apply them. </p> </section> </section> <section class="category"> <h1>Electives</h1> <section> <h2>CS488</h2> <h2>Computer Graphics Applications</h2> <p> This course is an introduction to 2-D and 3-D computer graphics that covers the material from the bottom up. That is, it starts with the mathematical foundations, then explores the algorithmic issues that arise when implementing those mathematical concepts, and then considers the practice of developing graphical applications (using existing libraries). </p> </section> </section> <footer> <p> Copyright (c) <a href="http://www.jmu.edu">James Madison University</a>. </p> </footer> <script type="text/javascript">registerHandlers();</script> </body> </html>
/** * Change the stylesheet */ function increaseFontSize() { "use strict"; // ECMAScript 5 var size; size = parseFloat(document.body.style.fontSize); if ((size <= 0) || isNaN(size)){size = 12;} document.body.style.fontSize = (size * 1.1) + "pt"; } /** * Register the event handlers */ function registerHandlers() { "use strict"; // ECMAScript 5 document.body.addEventListener("click", increaseFontSize, true); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="class-change.css" /> <title>Changing the class of an Element</title> <script src="class-change.js" type="text/javascript"></script> </head> <body> <p> <label>Weight (pounds):</label> <input type="text" id="weight" class="valid" /> </p> <script type="text/javascript">registerHandlers();</script> </body> </html>
/** * Register the event handlers */ function registerHandlers() { "use strict"; // ECMAScript 5 var weightField; weightField = document.getElementById("weight"); weightField.addEventListener("input", validateWeight, true); } /** * Validate the weight field */ function validateWeight() { "use strict"; // ECMAScript 5 var weight, weightField; weightField = document.getElementById("weight"); weight = parseInt(weightField.value, 10); if (isNaN(weight) || (weight < 0)){ weightField.className = "invalid"; }else{ weightField.className = "valid"; } }
document
object has a stylesheets
collectionstylesheets
has a
cssRules
collectionstyle
propertydocument.styleSheets[0].cssRules[i].style.color = "blue";
document.write()
to insert HTML text
into the documentnode = document.getElementById("result");
node = parent.firstChild
node = parent.childNodes[i]
newTextNode = document.createTextNode("...");
parent.replaceChild(node, newTextNode);
or parent.appendChild(newTextNode);
node.data = "...";
or
node.nodeValue = "...";
node.innerHTML = "...";
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="bmi-calculator.css" /> <title>BMI Calculator</title> <script src="bmi.js" type="text/javascript"></script> <script src="bmi-calculator.js" type="text/javascript"></script> </head> <body> <section> <p class="input"> <label>Weight (pounds):</label> <input type="text" id="weight" /> </p> <p class="input"> <label>Height (inches):</label> <input type="text" id="height" /> </p> </section> <section class="output"> <p class="output"> <label>BMI:</label> <span id="bmi"> </span> </p> <p class="output"> <label>Category:</label> <span id="category"> </span> </p> </section> <script type="text/javascript">registerHandlers();</script> </body> </html>
.normal { color: rgb(0, 101, 0); text-transform: capitalize; } .obese { color: rgb(204,0,0); text-transform: capitalize; } .overweight { color: rgb(255,153,0); text-transform: capitalize; } .underweight { color: rgb(255,153,0); text-transform: capitalize; } body { color: rgb(102,153,204); font-family: Arial; } input { text-align: right; border-color: rgb(102,153,204); border-radius: 5px; border-style: solid; border-width: 1px; } input:focus { background-color: rgb(255,255,204); } label { float: left; text-align: right; width: 50%; } p.input { margin: 0px; padding: 5px; text-align: right; } p.output { padding: 5px; text-align: right; } section { width: 400px; } section.output { background: rgb(255,240,220); border-color: rgb(110,110,100); border-radius: 5px; border-style: solid; border-width: 1px; } span { float: right; text-align: right; width: 50%; }
/** * Note: This is a good example of a situation in which an object-oriented * approach is preferred. Such an approach would enable us to retrieve the * fields once and then store them as properties of the object. */ /** * Register the event handlers */ function registerHandlers() { "use strict"; // ECMAScript 5 var heightField, weightField; weightField = document.getElementById("weight"); heightField = document.getElementById("height"); weightField.addEventListener("input", displayResults, true); heightField.addEventListener("input", displayResults, true); } /** * Display the results */ function displayResults() { "use strict"; // ECMAScript 5 var category, categoryDisplay, bmi, bmiDisplay, height, heightField, text, weight, weightField; weightField = document.getElementById("weight"); heightField = document.getElementById("height"); weight = parseFloat(weightField.value); height = parseFloat(heightField.value); // Clear the current results bmiDisplay = document.getElementById("bmi"); categoryDisplay = document.getElementById("category"); text = bmiDisplay.firstChild; text.data = " "; text = categoryDisplay.firstChild; text.data = " "; // Calculate the BMI bmi = calculateBMI(weight, height); // Display the results if (!isNaN(bmi)){ text = bmiDisplay.firstChild; text.data = bmi.toFixed(1); text = categoryDisplay.firstChild; category = "normal"; if (bmi <= 18.5 ){ category = "underweight"; }else if ((bmi >= 25) && (bmi < 30.0)){ category = "overweight"; }else if (bmi > 30){ category = "obese"; } text.data = category; // It will be capitalized categoryDisplay.className = category; /* Note: We could have changed the style property rather than the class, but this approach is better because it delegates all presentation decisions to the stylesheet. */ } }
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="addnodes.css" /> <script src="addnodes.js" type="text/javascript"></script> <title>Add Nodes to the Document Tree</title> </head> <body> <section id="prices"> <h1>Prices</h1> </section> <script type="text/javascript"> start(); </script> </body> </html>
h1 { background: rgb(102,153,204); border-color: rgb(102,153,204); border-style: solid; border-width: 1px; border-top-left-radius: 5px; border-top-right-radius: 5px; color: white; font-size: 14pt; text-align: center; margin: 0px; padding: 0px; } input:focus { background-color: rgb(255,255,204); } input { border-color: rgb(102,153,204); border-style: solid; border-width: 1px; border-radius: 5px; display: block; margin: 5px; margin-left: auto; margin-right: auto; width: 90%; } section { border-color: rgb(102,153,204); border-radius: 5px; border-style: solid; border-width: 1px; float: left; margin: 5px; }
function start() { "use strict"; // ECMAScript 5 var child, i, prices, size; size = window.prompt("Size?"); prices = document.getElementById("prices"); for (i=0; i<size; ++i){ child = document.createElement("input"); child.type = "text"; child.value = ""; prices.appendChild(child); } }
Document
ObjectbaseURI
and URL
:
base
element and full URL of the document,respectivelydomain
:
lastModified
:
referrer
:
cookie
:
isFinite()
and isNaN()
parseFloat()
and parseInt()
Date.parse()
escape()()
and unescape()
Location
objects have methods
for parsing URLswindow.setTimeout(statement,millis)
identifier = window.setInterval(statement,millis);
window.clearInterval(identifier);
<!DOCTYPE html> <html> <head> <title>An Example of a Splash Screen</title> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="splashscreen.css"/> <script src="splashscreen.js" type="text/javascript"></script> </head> <body> <header id="splashscreen" class="centered"> <img src="MultimediaBookCover.png" /> </header> <section> <h1>Sampled Static Visual Content</h1> <p> The sampling of static visual content involves the sampling of both the color spectrum and space (usually in that order). The two are similar in that they both involve the discretization of continuous information. They are different in their dimensionality. </p> <dl> <dt>Color Sampling</dt> <dd> A process for converting from a continuous (infinite) set of colors to a discrete (finite) set of colors. </dd> </dl> <p> Such processes are sometimes called quantization schemes. The result of color sampling (i.e., the discrete set of colors) is often referred to as a <em>palette</em>, though one has to be somewhat careful because this term is sometimes used to describe the set of actual samples and other times is used to describe the set of all possible samples. </p> <dl> <dt>Spatial Sampling</dt> <dd> A process for discretizing space. </dd> </dl> <p> Though there are many ways to perform spatial sampling, this book limits its attention to the plane and, in particular, with spatial sampling schemes that involve the use of a finite grid with cells of equal size. In essence, one places a regular grid on a planar surface and assigns a single color to each cell in the grid. </p> <p> The result of color sampling and spatial sampling is a matrix/table of picture elements (or <em>pixels</em>), each of which contains a single color in the palette. Such a matrix/table is often called a <em>raster representation</em>. One example is illustrated in the following Figure. In practice, sampled static visual content is usually created in one of two ways. In some cases, it is created using a <em>scanner</em> that samples from a source of some kind (e.g., a drawing or painting). In other cases, it is created on a computer by a person (who selects colors from a discrete set) using a pointing device of some kind (e.g., a mouse or a pen on a graphics tablet) that performs the spatial sampling. Two common examples of sampled static visual content are <em>bitmapped images</em> and <em>bitmapped fonts</em>. </p> <figure> <img src="raster.png"/> <figcaption> A Raster Representation </figcaption> </figure> </section> <script type="text/javascript">splash();</script> </body> </html>
/** * Setup the timer */ function splash() { "use strict"; // ECMAScript 5 window.setTimeout(removeSplashScreen, 2000); } /** * Remove the splash screen */ function removeSplashScreen() { "use strict"; // ECMAScript 5 var i, section, splashScreen; splashScreen = document.getElementById("splashscreen"); /* Append to the className property in case the element already has a class for other purposes */ splashScreen.className += " excluded"; /* Make the sections "visible" */ section = document.getElementsByTagName("section"); for (i=0; i<section.length; ++i) { section[i].style.display = "block"; } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="fishtank.css" /> <title>Fishtank</title> <script src="fishtank.js" type="text/javascript"></script> </head> <body> <section id="tank"> <img src="fish.png" id="fish" /> </section> <script type="text/javascript">setup();</script> </body> </html>
var fishTimer; /** * Setup the timer */ function setup() { "use strict"; // ECMAScript 5 fishTimer = window.setInterval(move, 40); } /** * Move the fish */ function move() { "use strict"; // ECMAScript 5 var fish, left; fish = document.getElementById("fish"); if ((fish.style.left === undefined) || (fish.style.left === "")){ left = 0; }else{ left = parseInt(fish.style.left, 10); } left += 1; if (left > 400){window.clearInterval(fishTimer);} fish.style.left = left+"px"; }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="ghost.css" /> <title>A Ghost (Using CSS Transitions)</title> <script src="ghost.js" type="text/javascript"></script> </head> <body> <section id="campus"> <img src="ghost.png" id="ghost"/> </section> <script type="text/javascript">setup();</script> </body> </html>
/** * Setup the event listener */ function setup() { "use strict"; // ECMAScript 5 var campus; campus = document.getElementById("campus"); campus.addEventListener("click", moveGhost, true); } /** * Move the ghost to its final position. * * Not: The CSS transition will handle the tweening (i.e., the * interpolation) */ function moveGhost(event) { "use strict"; // ECMAScript 5 var ghost; if (!event){event = window.event;} ghost = document.getElementById("ghost"); ghost.style.left = event.clientX + "px"; ghost.style.top = event.clientY + "px"; }