CSSE 290 Web Programming

Lecture 18: Unobtrusive JavaScript; Prototype Library

Reading: 10.1

Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.

Otherwise note: Claude Anderson was given permission to modify the slides for CSSE 290 at Rose-Hulman by author Jessica Miller. The authors' original slides, based on Web Programming Step by Step, can be seen at http://webstepbook.com.

Some of the examples in some days' slides are from David Fisher at Rose-Hulman, who was kind enough to allow me to use them. My intention is to mark these examples with [DSF].

Valid HTML Valid CSS!

10.1: The Prototype Library

Problems with JavaScript

JavaScript is a powerful language, but it has many flaws:

Prototype framework

<script src="../scripts/prototype.js" type="text/javascript"></script>

The $ function

$("id")

Recap: The DOM tree

DOM tree

Prototype's DOM element methods

absolutize addClassName classNames cleanWhitespace clonePosition
cumulativeOffset cumulativeScrollOffset empty extend firstDescendant
getDimensions getHeight getOffsetParent getStyle getWidth
hasClassName hide identify insert inspect
makeClipping makePositioned match positionedOffset readAttribute
recursivelyCollect relativize remove removeClassName replace
scrollTo select setOpacity setStyle show
toggle toggleClassName undoClipping undoPositioned update
viewportOffset visible wrap writeAttribute

Prototype's DOM tree traversal methods

method(s) description
ancestors, up elements above this one
childElements, descendants, down elements below this one (not text nodes)
siblings, next, nextSiblings,
previous, previousSiblings, adjacent
elements with same parent
as this one (not text nodes)
DOM element
// alter siblings of "main" that do not contain "Sun"
var sibs = $("main").siblings();
for (var i = 0; i < sibs.length; i++) {
	if (sibs[i].innerHTML.indexOf("Sun") < 0) {
		sibs[i].innerHTML += " Sunshine";
	}
}

Prototype's methods for selecting elements

Prototype adds methods to document (and all DOM elements) for selecting groups of elements:

getElementsByClassName array of elements that use given class attribute
select array of descendants that match given CSS selector, such as "div#sidebar ul.news > li" (identical to querySelectorAll on the element)
$$ equivalent to document.querySelectorAll
var gameButtons = $("game").select("button.control");
for (var i = 0; i < gameButtons.length; i++) {
	gameButtons[i].style.color = "yellow";
}

The $$ function

var arrayName = $$("CSS selector");
// hide all "announcement" paragraphs in the "news" section
var paragraphs = $$("div#news p.announcement");
for (var i = 0; i < paragraphs.length; i++) {
	paragraphs[i].hide();
}

Common $$ issues

Recap: JavaScript - Remove a node from the page

function slideClick() {
	var bullets = document.getElementsByTagName("li");
	for (var i = 0; i < bullets.length; i++) {
		if (bullets[i].innerHTML.indexOf("children") >= 0) {
			bullets[i].parentNode.removeChild(bullets[i]);
		}
	}
}

Prototype: Remove a node from the page

function slideClick() {
	var bullets = $$("li");
	for (var i = 0; i < bullets.length; i++) {
		if (bullets[i].innerHTML.indexOf("children") >= 0) {
			bullets[i].remove();
		}
	}
}

Problems with reading/changing styles

<button id="clickme">Click Me</button>
window.onload = function() {
	$("clickme").onclick = biggerFont;
};
function biggerFont() {
	var size = parseInt($("clickme").style.fontSize);
	size += 4;
	$("clickMe").style.fontSize = size + "pt";
}

Accessing styles in Prototype

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

Common bug: incorrect usage of existing styles

$("main").style.top = $("main").getStyle("top") + 100 + "px";            // bad!

JavaScript: Getting/setting CSS classes

function highlightField() {
	// turn text yellow and make it bigger
	if (!$("text").className) {
		$("text").className = "highlight";
	} else if ($("text").className.indexOf("invalid") < 0) {
		$("text").className += " highlight";
	}
}

Getting/setting CSS classes in Prototype

function highlightField() {
	// turn text yellow and make it bigger
	if (!$("text").hasClassName("invalid")) {
		$("text").addClassName("highlight");
	}
}