becoming a javascript wizard · title: basham becomingjavascriptwizard.odp author: peggy kovsky...
TRANSCRIPT
Becoming a JavaScript Wizard
Bryan Basham
Software Alchemist
http://www.linkedin.com/in/SoftwareAlchemist
Colorado Software Summit: October 19 – 24, 2008 © Copyright 2008, Bryan Basham
Bryan Basham — Becoming a JavaScript Wizard Slide 1
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 2
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 3
© Copyright 2008, Bryan Basham
Using Web Standards
Separation of Concerns: structure, presentation, and behavior
Why?
Supports multiple browsers and devices
Easy to modify and replace look and feel
Clarity of code
Brevity of code (reduces bandwidth)
Better accessibility and usability
“Write once, publish everywhere”
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 4
© Copyright 2008, Bryan Basham
Example / Demo
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 5
© Copyright 2008, Bryan Basham
Structure
XHTML (or HTML v4.01)
Markup validation
Semantic (not presentational) structure
<body> <div id='header'> <h1>MyCorp</h1> <ul id='main_navigation_list'> <li><a href='...'>Exams</a></li> <li><a href='...'>Surveys</a></li> </ul> </div> <div id='content'> <p>....</p> </div> ...</body>
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 6
© Copyright 2008, Bryan Basham
Presentation
Cascading Style Sheets (CSS)
Extremely powerful layout and styling
ul#main_navigation_list { list-style: none; margin: 0 0 0 110px; overflow: hidden; padding: 25px 0 0 0; width: 100%;}ul#main_navigation_list li { float: left; margin: 0; padding: 0 .5em;}ul#main_navigation_list li a { color:#fff; text-decoration: none;}
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 7
© Copyright 2008, Bryan Basham
Behavior
JavaScript (aka ECMAScript 262)
Rich object-based and functional language
Manipulate the page structure (DOM)
Handle user-generated events on elements
Handle sync and async communication with server
CONS: some inconsistencies between browsers
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 8
© Copyright 2008, Bryan Basham
Why is this important?
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Client
Server
UI Code
Data
Behavior
StructureStructure
Presentation
Behavior
Data
conversion
invoke
select next view
generate
enhanc
e
style / layout
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 9
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 10
© Copyright 2008, Bryan Basham
Data Types
Numbers (64-bit floating point)42 * 10.0 ==> 420typeof 42 ==> "number"typeof 4.2 ==> "number"
Strings (Unicode, ' and " delimited)"foo"'she said "he said"'typeof "foo" ==> "string"
Booleans (true and false, yes/no, 1/0)typeof true ==> "boolean"
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 11
© Copyright 2008, Bryan Basham
Data Types
Arrays
Objects
Functions
nulltypeof null ==> "object"
undefined typeof undefined ==> "undefined"
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 12
© Copyright 2008, Bryan Basham
Variables
Globalsvar G1 = 47;G2 = 100;
Localsfunction f() { var L1 = 47; return L1 + G1;}function g() { var G1 = 420; // this has local scope function h() { var G1 = 42; // nested scoping return G1; } return G1 + h();}g() ==> 462
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 13
© Copyright 2008, Bryan Basham
Namespace
Globals (vars and functions) create clutter
Helpful idiom:
var MySpace = {
G1 : 42,
square : function(x) { return x * x; },
configuration : { width : 100, height : 350 },
funct : function(x) { return MySpace.G1 * x; }}
MySpace.funct(10) ==> 420
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 14
© Copyright 2008, Bryan Basham
Arrays
Syntaxvar myArray = [13, 42, 47, 420];typeof myArray ==> "object" // Huh???
AccessmyArray.length ==> 4myArray[0] ==> 13myArray[3] ==> 420
Iterationfor ( var i=0; i<myArray.length; i++ ) { console.info("myArray[" + i + "] is " + myArray[i]);}
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 15
© Copyright 2008, Bryan Basham
Functions
Definition syntaxfunction square(x) { return x * x; }square(12) ==> 144typeof square ==> "function"
OR as a variablevar square = function(x) { return x * x; }; // lambda function (LISP)square(12) ==> 144
OR as an objectvar square = new Function("x", "return x * x;");square(12) ==> 144
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 16
© Copyright 2008, Bryan Basham
Functional Programming
Functions are first-class citizens
Example 1:function each(funct, array) { for ( var i=0; i<array.length; i++ ) { funct(array[i]); }}each( function(x) { console.info(x); }, myArray );
Example 2:function map(funct, array) { var newArray = new Array(); for ( var i=0; i<array.length; i++ ) { newArray[i] = funct(array[i]); } return newArray;}map( square, myArray ); ==> [169, 1764, 2209, 176400]
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 17
© Copyright 2008, Bryan Basham
Closures
Closures hold state within a functionfunction square(x) { return x * x;}
function makeCutoffFunction(nTimes, funct) { return function(x) { // creating a new function object nTimes--; // access to local state variable if ( nTimes >= 0 ) { return funct(x); // do the funct once } };}
var squareOnce = makeCutoffFunction( 1, square );squareOnce(12) ==> 144squareOnce(13) ==> void
var logThrice = makeCutoffFunction( 3, console.info );logThrice("first log message"); // log oncelogThrice("second log message"); // log twicelogThrice("third log message"); // log thricelogThrice("fourth log message"); // stops logging
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 18
© Copyright 2008, Bryan Basham
Objects
Creating an objectvar O1 = new Object();O1.a = 47;O1.method = function() { console.info(this.a); };typeof O1 ==> "object"
OR as a literalvar O1 = { a : 47, method : function() { console.info(this.a); }}
Access object attributesO1.a ==> 47O1.a = 42;O1.method() ==> displays '42' in the consoleO1["a"] ==> 42O1["a"] = 420;O1["method"]() ==> displays '420' in the console
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 19
© Copyright 2008, Bryan Basham
JavaScript Core Classes
Built-in
Object
Date
RegExp
Error (and subclasses)
Wrappers
String, Number, and Boolean
Odd balls
Function and Array
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 20
© Copyright 2008, Bryan Basham
But wait... no classes
You can't create classes in JavaScriptclass Range { /* code here */ } // NOT VALID
You can only create object constructorstypeof Date ==> "function"
var Range = function(start, end) { this.start = start; this.end = end;}
var r1 = new Range(42, 47);r1.start ==> 42r1.end ==> 47
var r2 = new Range(13, 420);r2.start ==> 13r2.end ==> 420
r1 #111:Range
start = 42end = 47
r2 #222:Range
start = 13end = 420
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 21
© Copyright 2008, Bryan Basham
Encapsulation
Ugh... these attributes are publicr2.start = 520;r2.start ==> 520 // Semantics broken: the “start” is now after the “end”
Closures allow us to hide private datavar Range = function(st, en) { var start = st; var end = en; this.getStart = function() { return start; } this.getEnd = function() { return end; }}
var r1 = new Range(42, 47);r1.start ==> undefinedr1.getStart() ==> 42r1.getEnd() ==> 47
var r2 = new Range(13, 420);r2.getStart() ==> 13r2.getEnd() ==> 420
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 22
© Copyright 2008, Bryan Basham
Encapsulation object model
r1 #111:Range
getStartgetEnd
#987:CallObj
start = 42end = 47
#876:CallObj
start = 13end = 420
function() { return start; }
function() { return end; }
r2 #222:Range
getStartgetEnd
function() { return start; }
function() { return end; }
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 23
© Copyright 2008, Bryan Basham
Encapsulation
Creating settersvar Range = function(start, end) {
this.getStart = function() { return start; }
this.setStart = function(x) { if ( x <= end ) start = x; }
this.getEnd = function() { return end; }
this.setEnd = function(x) { if ( x >= start ) end = x; }
}
var r = new Range(42, 47);
r.getStart() ==> 42
r.setStart(13)
r.getStart() ==> 13
r.setStart(50) // fails quietly; could throw an Error
r.getStart() ==> 13
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 24
© Copyright 2008, Bryan Basham
But... this too has problems
This pattern creates lots of object-specific functions
r1 #111:Range
getStartsetStartgetEndsetEnd
#222:Range
getStartsetStartgetEndsetEnd
function() {...}
function(x) {...}
function() {...}
function(x) {...}
function() {...}
function(x) {...}
function() {...}
function(x) {...}
r2
#987:CallObj
start = 42end = 47
#876:CallObj
start = 13end = 420
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 25
© Copyright 2008, Bryan Basham
Another class-like idiom
Constructors have prototypesvar Range = function(st, en) { this.start = st; this.end = en;}
// Setup shared Range object methodsRange.prototype.getStart = function() { return this.start; }Range.prototype.setStart = function(x) { if ( x <= this.end ) this.start = x;}Range.prototype.getEnd = function() { return this.end; }Range.prototype.setEnd = function(x) { if ( x >= this.start ) this.end = x;}
// Create a group of Range objectsvar r1 = new Range(42, 47);var r2 = new Range(13, 420);var r3 = new Range(1.2, 3.14);var r4 = new Range(1, 10);
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 26
© Copyright 2008, Bryan Basham
Another class-like idiom
Function objects are reused across all objects
Range.prototype
getStartsetStartgetEndsetEnd
function() {...}
function(x) {...}
function() {...}
function(x) {...}
r1 #111:Range
start = 42end = 47
r2 #222:Range
start = 13end = 420
r3 #333:Range
start = 1.2end = 3.14
r4 #444:Range
start = 1end = 10
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 27
© Copyright 2008, Bryan Basham
Hybrid OO idiom
var Circle = function(r) { // Private object attributes stored in the closure var radius = r; // Create privileged methods this.getRadius = function () { return radius; }}// Create public, but non-privileged methodsCircle.prototype.getDiameter = function() { return this.getRadius() * 2; }Circle.prototype.getArea = function() { return Circle.PI * this.getRadius() * this.getRadius(); }// Create class constantsCircle.PI = 3.14159;
var c1 = new Circle(4.2);c1.getRadius() ==> 4.2c1.getDiameter() ==> 8.4c1.getArea() ==> 55.4176476
var c2 = new Circle(10);c1.getRadius() ==> 10c1.getDiameter() ==> 20c1.getArea() ==> 314.159
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 28
© Copyright 2008, Bryan Basham
Object model of hybrid OO
Circle.prototype
getDiametergetArea
function() {...}
function() {...}
c1 #111:Circle
getRadius
#987:CallObj
radius = 4.2
#876:CallObj
radius = 13
c2 #222:Circle
getRadius function() { return radius; }
function() { return radius; }
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 29
© Copyright 2008, Bryan Basham
Advanced Class Features
Admittedly these “class-like” programming idioms are awkward
Mimicking class inheritance is even more complex
There are other, more advanced, inheritance mechanisms
Such as Prototypal inheritance
See Douglas Crawford on Resource (web) slide
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 30
© Copyright 2008, Bryan Basham
JavaScript Object Notation
JSON is the ability to convert strings to and from JavaScript objects.
var obj = { a: 42, b: “foo” };var objStr = JSON.stringify(obj); // "{"a":42,"b":"foo"}"var o2 = JSON.parse(objStr);o1 == o2; // falseo1 === o2; // false
But what about our objects?var c1 = new Circle(4.2);
var c1Str = JSON.stringify(c1); // "{}" WTF?!?! Where's my object?
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 31
© Copyright 2008, Bryan Basham
Hybrid-Class JSON Methods// If the class already exists, skipif ( ! Circle ) {
// Create the Circle class constructor function Circle(r) { ... };
// JSON related methods Circle.prototype.toJSON = function() { var dataString = this.getRadius().toJSON(); return MyJSON.makeClassWrapper("Circle", dataString); }; // The MyJSON class reviver function uses this static function Circle.parseJSON = function(dataString) { var radius = parseInt(dataString); return new Circle(radius); };
// Run unit tests var c = new Circle(42); var cStr = JSON.stringify(c); var newC = MyJSON.parse(cStr);
} // END of Circle definition check
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 32
© Copyright 2008, Bryan Basham
JSON for Circle
The Circle instance method toJSON performs
conversion from object to string.var c1 = new Circle(42);c1.getArea(); // 5541.76476var c1Str = JSON.stringify(obj); // '"\"Circle(42)\""'
The MyJSON.parse method uses a JSON reviver
to reconstruct these objects.var newC1 = MyJSON.parse(c1Str);newC1.getArea(); // 5541.76476
The Circle static method parseJSON performs
conversion from string to object.
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 33
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 34
© Copyright 2008, Bryan Basham
Client-Side Overview
The window object
The document object
The event model
Timed events
Ajax
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 35
© Copyright 2008, Bryan Basham
Window
The window object is the “global object”
Control methods: close, focus, blur, move, open, print, resize
window
navigator
frames[]
location
history
document
screen
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 36
© Copyright 2008, Bryan Basham
Document
The document object represents the
structure of the web page
Provides easy access to critical elements
document
anchors[]
applets[]
forms[]
images[]
links[]
body
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 37
© Copyright 2008, Bryan Basham
Document Example<html><head></head><body> <div id="login"> <form action="" id="Login_form"> <fieldset> <ol> <li> <label for="login_id"> Login <abbr title="identification">ID</abbr> </label> <input id="login_id" name="username" type="text" /> </li> <li> <label for="password">Password</label> <input id="password" name="userpass" type="password" /> <a href="#">go</a> </li> </ol> </fieldset> </form> </div></body></html>
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 38
© Copyright 2008, Bryan Basham
Document Example Model
<HTML>
<HEAD> <BODY>
<DIV>
<FORM>
<OL>
<LI>
<FIELDSET>
<LABEL> <A><LABEL>
<LI>
<INPUT “username”> <INPUT “userpass”>
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 39
© Copyright 2008, Bryan Basham
Forms
Form objects provide quick access to form elements
Login_form:Form
login_id:Input
type=textname=usernamevalue=b_basham
password:Input
type=textname=userpassvalue=MySecret
:Fieldset
elements
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 40
© Copyright 2008, Bryan Basham
Document Object Model
DOM Level 0
de-facto standard for pre-XHTML
DOM Level 1
DOM navigation and manipulation
DOM Level 2
XML namespace-aware
events
DOM Level 3 (in progress)
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 41
© Copyright 2008, Bryan Basham
Documents contain Elements which might contain a sequence of text and/or other elements.
DOM Type Hierarchy
Node
Document Element CharacterData
Text Comment
CDATASection
1
childNodes
parentNode 1
0..*
0..*
The relationship between the Element andthe abstract CharacterData type is implied bythe Node's ability to contain children of anyNode subtype, such as Text or Comment.
documentElementAKA: the root node
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 42
© Copyright 2008, Bryan Basham
Node is an abstraction for traversing and modifying a tree structure.
Node Interface
«CORBA Interface»
Node
nodeName : DOMStringnodeValue : DOMStringnodeType : int {enum of types}firstChild : NodelastChild : NodepreviousSibling : NodenextSibling : Node
insertBeforereplaceChildremoveChildappendChildhasChildNodes() : boolean
1
0..*
childNodes
parentNode
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 43
© Copyright 2008, Bryan Basham
A Document contains a single root Element
An Element can contain any number of subnodes: usually text and other elements.
Document Interface
«CORBA Interface»
Document
doctype : DocumentTypeimplementation : DOMImplementationdocumentElement : Element
createElement(tagName) : ElementcreateTextNode(data) : TextcreateCDATASection(data) : CDATASectiongetElementsByTagName(tagName) : NodeListgetElementById(elementId) : Element
«CORBA Interface»
Element
tagName : DOMString
hasAttribute(attrName) : booleangetAttribute(attrName) : DOMStringsetAttribute(attrName, attrValue)removeAttribute(attrName)getElementsByTagName(tagName) : NodeList
«CORBA Interface»
Node
1
documentElementAKA: the root node
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 44
© Copyright 2008, Bryan Basham
Node Example
LI:Element
LABEL:Element INPUT:Element A:Element
"password":Text "go":Text
parentNodefir
stChild
lastC
hildnextSibling
previousSibling
<li> <label for="password">Password</label> <input id="password" name="userpass" type="password" /> <a href="#">go</a></li>
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 45
© Copyright 2008, Bryan Basham
Node Example (reality check)<li> <label for="password">Password</label> <input id="password" name="userpass" type="password" /> <a href="#">go</a></li>
LI:Element
LABEL:Element INPUT:Element A:Element
"Password":Text "go":Text
firstChild lastChild
ws:Text ws:Text ws:Text ws:Text
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 46
© Copyright 2008, Bryan Basham
The Event Model(s)
Traditional (AKA Level 0)
event handlers as tag attributes (onclick)
event handlers set as Element properties
No event model in DOM Level 1
Standard event model in DOM Level 2
event listeners are registered with the element
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 47
© Copyright 2008, Bryan Basham
Event Types
Mouse:
click, dblclick, mousedown, mouseup, mouseover, mousemove, mouseout
Keyboard:
keypress, keydown, keyup
Window:
load, unload, resize, scroll, abort, error
Form:
focus, blur, select, change, reset, submit
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 48
© Copyright 2008, Bryan Basham
Event Propagation
Netscape Model
Element1
Element2
Event Bubbling
Element1
Element2
Event Capturing
Microsoft Model
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 49
© Copyright 2008, Bryan Basham
Traditional Event Model
Assign handler on tag attribute<a href=”#” onclick=”return LoginScreen.validateForm();”>go</a>
Assign handler with element propertyvar goButton = document.getElementById('goButton');goButton.onclick = function(event) { return
LoginScreen.validateForm(); };
CONS:
Limited to only one handler per element and event type
Poor separation of concerns: behavior mixed in with structure
Inconsistent event propagation
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 50
© Copyright 2008, Bryan Basham
DOM Level 2 Events
HTML elements are event targets:
«CORBA Interface»
EventTarget
addEventListener(listener)removeEventListener(listener)dispatchEvent(event)
«CORBA Interface»
EventListener
handleEvent(event)
0..*
«CORBA Interface»
Event
type : DOMString
target : EventTarget {an element}currentTarget : EventTargeteventPhase : EventPhaseEnumtimeStamp : DOMTimeStamp
stopPropagation() : voidpreventDefault() : void
EventPhaseEnum
CAPTURING_PHASE = 1AT_TARGET = 2BUBBLING_PHASE = 3
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 51
© Copyright 2008, Bryan Basham
Standard Event Propagation
The standard propagation model is a combination of the proprietary models:
Element1
Element2
CAPTU
RE_PH
ASE
BU
BBLIN
G_PH
ASE
AT_TARGET
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 52
© Copyright 2008, Bryan Basham
Event Registration (HTML)<body onload="EventsLevel2.registerHandlers(false);">
<h1>Event Model: Level 2 w/ No Capturing</h1>
<div id="outerBox"> Element1
<div id="innerBox">
Element2 </div>
</div>
</body>
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 53
© Copyright 2008, Bryan Basham
Event Registration (JS)// Create the EventsLevel2 namespace var EventsLevel2 = {
handleEvent : function(event) {
var div = event.currentTarget; console.info("Current target: " + div.id
+ " had event: " + event
+ " in phase: " + event.eventPhase);
var propagate = confirm("Click OK to propagate the event.");
if ( ! propagate ) event.stopPropagation();
},
registerHandlers: function(capture) {
var outerBox = document.getElementById('outerBox');
var innerBox = document.getElementById('innerBox'); outerBox.addEventListener("click", EventsLevel2, capture);
innerBox.addEventListener("click", EventsLevel2, capture);
},
} // END of EventsLevel2 namespace definition
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 54
© Copyright 2008, Bryan Basham
Timed Events Example
The Window object includes methods to setup periodic activities.
For example, a clock:
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 55
© Copyright 2008, Bryan Basham
Timing with setInterval
var Clock = {
displayTime : function(event) { var time = // calculate the time string from new Date()
var clockBox = document.getElementById('clockBox');
clockBox.innerHTML = time;
}, toggleActivation : function() {
Clock.ACTIVE = ! Clock.ACTIVE;
if ( Clock.ACTIVE ) {
Clock.INTERVAL_ID = setInterval(Clock.displayTime, 1000); document.getElementById('actButton').value = "Stop Clock";
} else {
clearInterval(Clock.INTERVAL_ID); document.getElementById('actButton').value = "Start Clock";
}
},
ACTIVE : false, INTERVAL_ID : 0,
} // END of Clock namespace definition
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 56
© Copyright 2008, Bryan Basham
Timing with setTimeoutvar Clock = {
displayTime : function(event) {
var time = // calculate the time string from new Date()
var clockBox = document.getElementById('clockBox'); clockBox.innerHTML = time;
Clock.TIMEOUT_ID = setTimeout('Clock.displayTime()', 1000);
}, toggleActivation : function() {
Clock.ACTIVE = ! Clock.ACTIVE;
if ( Clock.ACTIVE ) {
Clock.TIMEOUT_ID = setTimeout('Clock.displayTime()', 1000); document.getElementById('actButton').value = "Stop Clock";
} else {
clearTimeout(Clock.INTERVAL_ID);
document.getElementById('actButton').value = "Start Clock"; }
},
ACTIVE : false, TIMEOUT_ID : 0,
} // END of Clock namespace definition
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 57
© Copyright 2008, Bryan Basham
Ajax
Asynchronous JavaScript and XML
perform HTTP requests without a page refresh
responses are small chunks of data or content
use DOM scripting to modify the current page
User or timed events can trigger JS code to invoke an HTTP request
The XMLHttpRequest class is not yet a
standard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 58
© Copyright 2008, Bryan Basham
Creating an Ajax requestvar MyAjax = { createRequest : function() {
var request;
try {
request = new XMLHttpRequest(); } catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) { console.error(failed);
request = null;
}
} }
return request;
},} // END of MyAjax namespace definition
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 59
© Copyright 2008, Bryan Basham
Handling an Ajax requestvar MyAjax = {
createRequest : {}, // from previous slide
sendRequest : function(url, requestData, callbackFunction) { var request = MyAjax.createRequest();
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/x-javascript;");
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
if (request.responseText) { callbackFunction(request.responseText);
}
}
}; request.send(JSON.stringify(requestData));
},
} // END of MyAjax namespace definition
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 60
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 61
© Copyright 2008, Bryan Basham
JavaScript Frameworks
Even with the DOM and Level 0 APIs, client-side JavaScript is rather primitive.
Browsers have differing level of support for client-side APIs and bugs.
Many groups have built frameworks to:
smooth out the bugs
build higher level APIs
create UI widgets
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 62
© Copyright 2008, Bryan Basham
Prototype...
is a framework that provides low-level tools that extend basic JavaScript
creates work-arounds for browser bugs
provides APIs for higher-level programming
selecting DOM elements
better DOM traversal and manipulation
more functional programming
easier Ajax
more flexible event processing
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 63
© Copyright 2008, Bryan Basham
Element Selectors
The $ function selects an HTML element by its id
$('myID') === document.getElementById('myID')
$('id1', 'id2') === [ $('id1'), $('id2') ]
The $$ function selects a collection of HTML
elements
$$('li') === document.getElementsByTagName('li')
$$('#myID') === [ $('myID') ]
$$('div.MyCssClass') ==> array of DIV elements with the MyCssClass class
$$('ol#section2 > li') ==> array of LI elements within the OL element named 'section2'
and many more selection constructs; most are based on CSS selectors
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 64
© Copyright 2008, Bryan Basham
DOM Enhancements
The $ and $$ functions returns DOM
elements but with additional methods
Visibility: hide, show, toggle, visible
Element class: addClassName, removeClassName,
toggleClassName, hasClassName
Style: getStyle, setStyle
Attributes: readAttribute, writeAttribute
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 65
© Copyright 2008, Bryan Basham
DOM Enhancements
Navigation
Basic: up, down, next, previous
Up/Down: ancestors, descendants, immediateDescendants
Across: siblings, nextSibling, previousSibling
ignores text nodes
Manipulation: update, replace, insert, remove, wrap
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 66
© Copyright 2008, Bryan Basham
Functional Programming
List processing: each, map, pluck
Searching: detect, select, reject, partition
Sorting: sortBy, min, max
Other “Enumerable” objects:
$A() creates an Enumerable array
$H() creates an Enumerable hash map
$R(min, max) creates an Enumerable numeric range
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 67
© Copyright 2008, Bryan Basham
Easier Ajax
Raw Ajax processing is cumbersome
The Request class provides higher-level APInew Ajax.Request('getData.jsp', { method: 'get', onComplete: function() { /* handle response data */ }
});
The Updater provides element modificationnew Ajax.Updater('myElement', 'getHtmlChunk.jsp', { method: 'get' });
The PeriodicalUpdater updates on an interval
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 68
© Copyright 2008, Bryan Basham
Easier Event Handling
Two distinct event models (pre- and post-DOM) is troublesome
Observing$('testButton').observe('click', MyScreen.handler1);
$('testButton').observe('click', MyScreen.handler2);
DOM loadingEvent.observe(window, 'load', MyScreen.initialize);
Before the <body onload=''> handler
...but after DOM has completely loaded
Prototype supports custom event handling
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 69
© Copyright 2008, Bryan Basham
script.aculo.us...
is a framework that provides high-level tools that extend widgets functionality
is built on top of Prototype
provides APIs for widget programming
effects
drag-and-drop
widgets: in-place editing, auto-completer, slider
sound APIs
additional DOM building APIs
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 70
© Copyright 2008, Bryan Basham
Effects
Effects perform element animation
to show motion
to alert user to new content
to show user what has changed
Core: Effect.Morph / Effect.Move /
Effect.ScrollTo / Effect.Scale / Effect.Highlight
Hiding: Effect.Fade / Effect.BlindDown /
Effect.SlideDown
Showing: Effect.Appear / Effect.BlindUp /
Effect.SlideUp
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 71
© Copyright 2008, Bryan Basham
Drag and Drop
Making draggables:new Draggable('myElement', options);
Making droppables:Droppables.add('myElement', options);
SortableSortable.create('myElement', options);
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 72
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 73
© Copyright 2008, Bryan Basham
Other JS tools
jQuery is an alternate to Prototype and script.aculo.us
Other UI widget sets:
Google Web Toolkit (GWT)
ExtJS
YahooUI Library
DOJO
Lots of other libraries (click here)
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 74
© Copyright 2008, Bryan Basham
Topics Mind Map
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 75
© Copyright 2008, Bryan Basham
Building JS Components
Build classes to represent data on the client-side
Build classes for client-side UI widgets; possibly in conjunction with JSF
Build namespaces for screen-specific functionality
event handlers
timed event handlers
Ajax handlers
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 76
© Copyright 2008, Bryan Basham
Example / Demo
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 77
© Copyright 2008, Bryan Basham
Q & A
Introduction
Prototype& Scriptaculous
LanguageFundamentals
Client-sideAPIs
Other tools
Roll Your Own
JavaScriptWizard
Colorado Software Summit: October 19 – 24, 2008
Bryan Basham — Becoming a JavaScript Wizard Slide 78
© Copyright 2008, Bryan Basham
Resources
Head First JavaScript (O'Reilly)
JavaScript – The Definitive Edition (O'Reilly)
DOM Scripting (friends of ed)
Practical Prototype and script.aculo.us (Apress)
designing with web standards, 2nd ed. (New Riders)
Mozilla: site
ECMAScript standard: site and PDF
Douglas Crawford's site and lectures
JSON
Prototype
script.aculo.us
Others: jQuery, ExtJS, YUI, GWT, Dojo, and so many more