|
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";
}