Web Programming Step by Step

Lecture 14
Unobtrusive JavaScript

Reading: 8.1 - 8.2

Except where otherwise noted, the contents of this presentation are Copyright 2010 Marty Stepp and Jessica Miller.

Valid XHTML 1.1 Valid CSS!

8.1: Global DOM Objects

The six global DOM objects

Every Javascript program can refer to the following global objects:

namedescription
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

The window object

the entire browser window; the top-level object in DOM hierarchy

The document object

the current web page and the elements inside it

The location object

the URL of the current web page

The navigator object

information about the web browser application

The screen object

information about the client's display screen

The history object

the list of sites the browser has visited in this window

Unobtrusive JavaScript (8.1.1)

Obtrusive event handlers (bad)

<button onclick="okayClick();">OK</button>
// called when OK button is clicked
function okayClick() {
	alert("booyah");
}

Attaching an event handler in JavaScript code

// where element is a DOM element object
element.event = function;
<button id="ok">OK</button>
$("ok").onclick = okayClick;

When does my code run?

	<head>
		<script src="myfile.js" type="text/javascript"></script>
	</head>

	<body> ... </body>
// global code
var x = 3;
function f(n) { return n + 1; }
function g(n) { return n - 1; }
x = f(x);

A failed attempt at being unobtrusive

	<head>
		<script src="myfile.js" type="text/javascript"></script>
	</head>

	<body>
		<div><button id="ok">OK</button></div>
// global code
$("ok").onclick = okayClick;   // error: $("ok") is null

The window.onload event (8.1.1)

// this will run once the page has finished loading
function functionName() {
	element.event = functionName;
	element.event = functionName;
	...
}

window.onload = functionName;   // global code

An unobtrusive event handler

<!-- look Ma, no JavaScript! -->
<button id="ok">OK</button>
// called when page loads; sets up event handlers
function pageLoad() {
	$("ok").onclick = okayClick;
}

function okayClick() {
	alert("booyah");
}

window.onload = pageLoad;  // global code

Common unobtrusive JS errors

Anonymous functions (8.1.2)

function(parameters) {
	statements;
}

Anonymous function example

window.onload = function() {
	var okButton = document.getElementById("ok");
	okButton.onclick = okayClick;
};

function okayClick() {
	alert("booyah");
}
window.onload = function() {
	var okButton = document.getElementById("ok");
	okButton.onclick = function() {
		alert("booyah");
	};
};

The keyword this (8.1.3)

this.fieldName                  // access field
this.fieldName = value;          // modify field

this.methodName(parameters);    // call method

Event handler binding

function pageLoad() {
	$("ok").onclick = okayClick;   // bound to okButton here
}

function okayClick() {           // okayClick knows what DOM object
	this.innerHTML = "booyah";     // it was called on
}

window.onload = pageLoad;

Fixing redundant code with this

<fieldset>
	<label><input type="radio" name="ducks" value="Huey"  /> Huey</label>
	<label><input type="radio" name="ducks" value="Dewey" /> Dewey</label>
	<label><input type="radio" name="ducks" value="Louie" /> Louie</label>
</fieldset>
function processDucks() {
	if ($("huey").checked) {
		alert("Huey is checked!");
	} else if ($("dewey").checked) {
		alert("Dewey is checked!");
	} else {
		alert("Louie is checked!");
	}
	alert(this.value + " is checked!");
}

Common bug: Getting existing styles

this.style.fontSize = this.style.fontSize + 10 + "px";            // bad!

Accessing styles in Prototype (9.1.4)

function biggerFont() {
	// turn text yellow and make it bigger
	var size = parseInt($("clickme").getStyle("font-size"));
	$("clickme").style.fontSize = (size + 4) + "pt";
}

Unobtrusive styling (8.2.3)

function okayClick() {
	this.style.color = "red";
	this.className = "highlighted";
}
.highlighted { color: red; }