KEMBAR78
Ajax and JavaScript Bootcamp | PPT
JavaScript Bootcamp Alexei White - Nitobi
A bit about me Development: Ruby/Rails, PHP, Coldfusion, Some ASP.NET, C++ back in the day, Turbo Pascal, etc, etc Design Enterprise Ajax Recent Projects: CompleteUI Component Suite Nintendo RobotReplay SayZu
About Nitobi Rich Internet Application development. Off-the-shelf Ajax UI components Cross Platform Java ASP.NET PHP Coldfusion Classic ASP Ruby on Rails
Bootcamp Goals Develop practical understanding of ECMAScript Actual coding Not too deep, not too shallow Remove mystery behind Rich Internet Applications Expose the trouble spots
Today’s Format Part 1 (Basics) Lexical Structure Datatypes Variables Operators, Expressions & Statements 10 minute break Part 2 (More Advanced) Debugging Basic DOM Exercise 1 Threading JavaScript & DHTML Exercise 2 10 minute break Part 3 (More Advanced) Object Oriented Programming Ajax (XHR) DOM Events Exercise 3
JavaScript Gotcha’s These slides will highlight Some browser-specific difficulty General wierdness Something else
IDE’s - PC Aptana Studio Integrated Debugging (IE/FF) Library Support AIR, Rails, PHP, etc SVN Support Visual Studio Integrated debugging Great Project Support Intellisense JSEclipse Text Editor Notepad++, Textedit Dreamweaver - MAC Textmate project support syntax highlighting snippets Aptana JSEclipse Text Editor’s I recommend
Part 1 The Basics
Essence of JavaScript (1/2) JavaScript != Java JavaScript != Simple
Essence of JavaScript (2/2) ECMAScript Dynamic Client-side Prototype based Associative arrays Weakly typed Obj.x = 10; Obj[“x”] = 10;
Understanding the Client-Server Boundary JavaScript has no secrets Client is unknown Dynamic – eval() Cross-site communication restricted
The impact of Browsers Sandbox implementation errors Minor implementation differences JavaScript Cascading Style Sheets Layout Supported media types
What Can you do in JavaScript? Draw boxes, images, and text Open and close windows Animate on-screen contents Modify the document Communicate with the server Talk to Java, Flash, Silverlight Snoop on the user.. record what they do. Read the mouse/keyboard
What it can’t do (1/2) Can’t open files Write to the file system Talk directly to hardware Read freely from memory Perform general networking open a socket etc Do Ajax across domains “ Security Sandbox”
What it can’t do (2/2) Can’t close windows willy-nilly Hide the destination of links Open windows that are too small Set the value of FileUpload fields Rotate graphics Make sound
JAVASCRIPT BASICS Lexical Structure
Lexical Structure All Unicode, all the time UTF-16 can represent most languages String operators respect encoding Case Sensitive (Most of the time) >>> var A = 1; >>> var a = 2; >>> a 2 >>> A 1 var a = 0; WHILE(a <= 2) { a+=1; }; var a = 0; while (a <= 2) { a+=1; };
Lexical Structure Whitespace ignored Optional semicolons var a = 2; if (a == 2) console.log('yep'); console.log('Carrying on'); var a = 2; if (a == 2) console.log('yep'); console.log('Carrying on'); a = 3 b = 4 Will be executed as a = 3; b = 4; return true; Will be executed as return; true; But you probably meant return true;
Whitespace & Semicolons Filesizes reduced by removing whitespace Missing semicolons can cause JS errors a = 3 b = 4 Will be become a = 3 b = 4 No Worky
Lexical Structure Comments Literals // This is a single-line comment. /* This is also a comment */  // here is another comment /*  * This is a multiline comment * */ 12  // The number 12 “ hello world” // A string of text ‘ hey now’ // Another string true // A boolean value /javascript/gi // A “regular expression” literal Null // Absense of an object
Lexical Structure Object Literals  Identifiers (Variables) { name: “Alexei”, weight: 160 } // An object initializer [23,345,12,341,2] // An array initializer [{a:2},{a:56,name:’Buck’},{c:65}] // An array of objects.. a my_variable_name v382 _something $ $fgj 34fg .vgf
Lexical Structure Reserved Words Reserved & Special break case catch continue default delete do else false finally for function if in instanceof new null return switch this throw true try typeof var void while with abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile A biggie
Lexical Structure Words to avoid arguments Array Boolean console Date decodeURI decodeURIComponent encodeURI Error escape eval EvalError Function Infinity isFinite isNan Math NaN Number Object parseFloat parseInt RangeError ReferenceError RegExp String SyntaxError TypeError undefined unescape URIError A biggie
JAVASCRIPT BASICS Datatypes
Datatypes Number String Boolean null undefined Objects Arrays Functions Dates RegExp Error Primitive types Reference types
Datatypes – Useful Information Numbers All floating point 64 bit (huge) (+/-) 1.7976931348623157x10 308 Small: 1.474334E-32 Hexadecimal Literals 0xff  , 0xCAFE911 Numeric Constants Infinity, NaN, Number.MAX_VALUE, Number.NEGATIVE_INFINITY
Datatypes – Useful Information Strings Modern ECMAScript implementations support Unicode Escape sequences: ‘ You\’re always saying what can\’t be done’ \u for unicode (eg: \u03c0 for   ) Concatenation Myname = first_name + ‘ danger ‘ + last_name; Strings are objects Myname.length, Myname.indexOf() Convert numbers to strings Msg = 100 + ‘’;  Msg = String(100);  Msg = 100.toString(); Strings to Numbers Myval = parseInt(“3 people”) // 3
Datatypes – Useful Information Boolean Values Often the result of comparisons (a == 4) Used in control structures: Type conversions are often automatic Numeric : true == 1, false == 0 Type conversion is easy if (a == 4) b = b + 1; else b = b – 1; c = true + true  // 2 d = true + ‘’  // ‘true’ var x = Boolean(1); // true a = 1; var y = !!a; // true
Datatypes – functions Functions can be stored in variables, arrays, etc. Can define lambda or anonymous functions function square(x) {  // function is called square, expects 1 argument return x*x;   // the function squares its arg and returns result }   // function ends here function square(x) { return x*x; } var square = function(x){ return x*x; } =
Datatypes – objects JavaScript has built-in objects Objects are associative arrays Invoked using  new  keyword document.forms document.images window.innerWidth window.scrollY document.forms document.images document[“forms”] document[“images”] = var a = new Object(); var now = new Date(); var pattern = new RegExp( “\\sjava\\s ”, “i”) a.x = 1.1;  a.y = 344;
Datatypes – objects Object literals Comma-separated list of name-value pairs AKA JSON (JavaScript Object Notation) var vertex = { x:3.2, y:13.2, z:64.3 };  var user = { &quot;fullName&quot;: &quot;John Smith&quot;, &quot;address&quot;: { &quot;streetAddress&quot;: &quot;21 2nd Street&quot;, &quot;city&quot;: &quot;New York&quot;, &quot;postalCode&quot;: 10021 }, &quot;phoneNumbers&quot;: [ &quot;212 732-1234&quot;, &quot;646 123-4567&quot; ] }
Datatypes – objects Object conversion: Does an object exist? Objects as strings if (myObj) { // Do something } a = {b:34,t:4} b = a + “” // “[object Object]”
Datatypes - arrays A collection of values, like an object Can contain any type of JS data var a = new Array(1.1, “something”, true, {x:43,y:34}); var b = new Array(); b[0] = 1.1; b[1] = “something”; b[2] = true; b[3] = {x:43,y:34}; var c = new Array(20);
Datatypes - arrays Array literals Sparse arrays Array length Searching var a = [1.2, “something”, true, {x:33,y:34}]; var a = [1,,,,5]; a.length var array = [2, 5, 9]; var index = array.indexOf(5); // index is 1 index = array.indexOf(7);  // index is -1
Datatypes – null & undefined null Indicates no value No object Converts to false in Boolean context (if (null)) undefined Not null Used when a variable is declared but has no value Comparing the two null == undefined null !== undefined
Datatypes - dates Not a fundamental type, but a class of object Easily use local or GMT time. Date math, and type conversion var now = new Date(); // create an object holding current   // date and time var xmas = new Date(2007,11,25); xmas.setFullYear(xmas.getFullYear() + 1);  // Next christmas var weekday = xmas.getDay(); // Day of week console.log(“Today is: “ + now.toLocaleString()); // Convert to string More on this Later!
Datatypes – regular expressions Pattern matching Search and replace Use the string method replace /^NITOBI/ /[1-9][0-9]*/ /\bnitobi\b/i Mystr.replace(/\bnitobi\b/I, “NITOBI”);  // capitalize all instances  // of NITOBI.
Datatypes – error objects Represents a runtime error Besides the base Error, there are six other core error types in JavaScript EvalError RangeError ReferenceError SyntaxError TypeError URIError Contains the following properties: constructor message name prototype try { throw new Error(&quot;Whoops!&quot;); } catch (e) { alert(e.name + &quot;: &quot; + e.message); } More on this Later!
Comparing Types Equality vs Identity Inspecting an identifier (typeof) var a =1; var b = true; a == true; // true a === true; // false b === true; // true a !== true; // true typeof(a); // “number” typeof(b); // “boolean”
Value vs Reference 3 ways to manipulate data values Copy it Pass it as an argument Compare it 2 ways to manipulate variables By value By reference
Value  vs Reference // copying by Value var a = 1; var b = a; // copy by value.. Two distinct values now // passing an argument by Value function add_to_sum(sum, x) { sum = sum + x; // this only changes the internal } // copy of x add_to_sum(a,1); if (b == 1) b = 2; // b is a distinct numeric value // a is still 1, and b is 2 Won’t actually do anything
Value vs  Reference // copying by reference var xmas = new Date(2007, 11, 25); var gift_day = xmas; // both variables refer to the same object gift_day.setDate(26); // we’ve now changed both variables function add_to_sum(sum, x) { sum[0] = sum[0] + x; sum[1] = sum[1] + x; sum[2] = sum[1] + x; } (xmas == gift_day) // this is true still xmas.getDate(); // returns 26 not 25 var newdate1 = new Date(2007,10,10); var newdate2 = new Date(2007,10,10); (newdate1 == newdate2)  // this is false Permanently changes ‘sum’ in global context Note: Strings are compared by value
JAVASCRIPT BASICS Variables
Typing JavaScript is weakly typed A variable can hold a value of any type at any time i = 10; i = “ten”; OK, no problem.
Variable Declaration Explicit declaration not required Implicit declaration has scope consequences Repeated declaration OK too. var i; var sum; var i, sum; var message = “hello”; var i = 0, j = 0, k = 43; var i = 1; // 1 var i = 2; // 2
Variable Scope Global – available everywhere Local – available within a function Local > Global var scope= “global”; function checkscope() { var scope = “local”; console.log(scope); // prints ‘local’; } console.log(scope); // prints ‘global’; Note: No Block Scope except SWITCH & WITH
Variable Scope var x = 1; function f() { } function g() { }
Garbage Collection Memory allocated and deallocated automatically Interpreter detects when allocated memory is unreachable var s = “hello”; // allocate some mem var u = s.toUpperCase(); // copy the value to a new string s = u; // “hello” now unreachable and is destroyed
Explorer Memory Leaks Circular references can cause memory leaks. Object A Object B Object A References B Object B References A
JAVASCRIPT BASICS Operators, Expressions & Statements
Operators Operator Operand type(s) Operation performed . Object, identifier Property access [ ] Array, integer Array index ! Boolean Logical complement == Any Equality === Any Identity && Booleans Logical AND || Booleans Logical OR ?: Booleans, any, any Conditional operator , Any Multiple evaluation
Assignment with Operation Operator Example Equivalent += a += b a = a + b -= a -= b a = a – b *= a *= b a = a * b /= a /= b a = a / b %= a %= b a = a % b <<= a <<= b a = a <<b >>= a >>= b a = a >>b >>>= a >>>= b a = a >>> b &= a &= b a = a & b |= a |= b a = a | b ^= a ^= b a = a ^ b
Conditional Operator (?:) Ternary operator (three operands) is equivalent to.. Fast, and compact. greeting = “hello “ + (username != null ? username : “there”); greeting = “hello “; if (username != null) greeting += username; else greeting += “there”; Don’t rely on a compiler for code optimization
Notes about Statements Brackets around expressions are required Single statements do not require curly-braces Whitespace ignored if ( expression ) statement if ( expression ) statement if ( expression ) { statement statement } if ( expression )  statement  else  statement
If / else if Execute multiple pieces of conditional code if (n == 1) { // Execute code block 1 } else if (n == 2) { // Execute code block 2 } else if (n == 3) { // Execute block 3 } else { // if all else fails, do this } if (n == 1) { // block 1 } else { if (n == 2) { // block 2 } else { if (n == 3) { // block 3 } else { // do this } } } Equivilent
Switch Better if you are just checking the same var over and over switch(n) { case 1: // start here if n == 1 // code block 1 break; case 2: // code block 2 break; case 3: // code block 3 break; default: // if all else fails… // code block 4 break; } Only use constants in CASE expressions
while, do/while var count = 0; while (count < 10) { console.log(count); count++; } var count = 0; do { console.log(count); count++; } while (count < 10) Will execute at least once
for for( initialize  ;  test  ;  increment ) statement for (var count = 0; count < 10; count++) console.log(count); for( variable  in  object ) statement var o = {x:1, y:2, z:3} var a = new Array(); var I = 0; for(a[i++] in o) {} Curly braces {} are not required if just one statement Copies the object “o” to the array “a” Not all properties are enumerable!
Performance Pitfall Array.length is expensive better: best: for (var count = 0; count < myarray.length; count++) console.log(count); for (var count = 0, mylen = myarray.length; count < mylen; count++) console.log(count); for (var count = myarray.length-1; count > 0; count--) console.log(count); re-calculated EVERY TIME  --SLOW-- !!
labels Any statement may be labeled Usually just used for loops Used for breaking and continuing myloop: while(something != null) { // code block }
break Causes the innermost enclosing loop or switch to exit. Can be combined with labels break; outerloop: for(var i = 0; i < 10; i++) { innerloop:   for(var j = 0; j < 10; j++) { if (j > 3) break;   // quit innermost loop if (i == 2) break innerloop; if (i == 4) break outerloop;   } }
continue Like break.. but just skips to the next iteration of the current loop Can be used with labels for(i = 0; i < data.length; i++) { if (data[i] == null) continue; total += data[i]; }
try/catch/finally/throw Create an exception Custom exceptions try { 43534987yhfh // clearly an error } catch(myerr) { console.log(myerr); } finally { //code block } try { throw(“User entered invalid data..”); } catch(myerr) { console.log(myerr); } finally { //code block } always executes regardless of what happens in catch() or try() Will write “Something bad happened..”
with Code block that modifies the scope chain Generally avoided. slow some unexpected behaviors (with init’d vars) with(frames[1].document.forms[0]) { // access form elements directly here. eg: name.value = “something”; address.value = “someplace”; email.value = “me@home.com”; }
; (empty) Has no effect.. but can be useful. var o = {x:1, y:2, z:3} var a = new Array(); var I = 0; for(a[i++] in o) ;
Part 2 More Advanced
ADVANCED JAVASCRIPT Debugging
Firebug Free Firefox plugin (http://www.getfirebug.com) Shows you 2 important things: What’s going on in your page when it loads & After it loads Advanced features Code profiling CSS debugging DOM Inspection JavaScript breakpoints and step-through XHR Debugging JSON Object Inspection Integration with Aptana
MS Script Debugger Step over, into Console window Not much else Visual Studio better (if you have it)
IE Developer Toolbar Useful for debugging CSS in IE Lacks many of the features in Firebug Convenient cache clearing Change CSS attributes on the fly Inspect Cache DOM browsing
Firebug Lite JavaScript extension for NON-Firefox browsers Mimics some of the console features of  Firebug Evaluate JavaScript in-line Makes cross-browser testing a lot easier.
Drosera - Safari WebKit JS debugger Code stepping DOM Inspection Mac-only
ADVANCED JAVASCRIPT Basic DOM
JavaScript in the Browser JavaScript should be unobtrusive Separation of concerns Keep it away from markup Modularize it Degrade gracefully* <html> <head> <script type=&quot;text/javascript&quot; src=&quot;code.js”></script> </head> <body> </body> </html> Sometimes this is real hard
Window window is global context literally means the browser window global variables can be referred to as window.variable Document object is a member Contains a hierarchical representation of document. Contains window info Geometry scroll position window.innerHeight window.innerWidth
Window Geometry Browser Differences Browser window.innerHeight document.body.clientHeight document.documentElement.clientHeight Opera 9.5+ strict window document window Opera 9.5+ quirks window window document Opera 7-9.2 window window document Opera 6 window window N/A Mozilla strict window document window Mozilla quirks window window document KHTML window document document Safari window document document iCab 3 window document document iCab 2 window window N/A IE 6+ strict N/A document window IE 5-7 quirks N/A window 0 IE 4 N/A window N/A ICEbrowser window window document Tkhtml Hv3 window window document Netscape 4 window N/A N/A
onload Event Handler onload fires after all HTML, CSS, Images, and JS is downloaded to the client. At this time, all JavaScript functions and objects part of the window object have been registered. <html> <head> <script type=&quot;text/javascript&quot; src=&quot;code.js”></script> </head> <body  onload=“myFunction()” > </body> </html>
Document Object Model Tree-structure document  elements, attributes, and text text nodes are immutable
Form Objects, fields, etc Forms are held in a collection Elements accessible as an array or an object var myForm = document.forms[&quot;customerForm&quot;]; myForm = document.customerForm; for (var i = 0, j = myForm.length; i < j; i++) console.log(myForm[i].value); console.log(myForm.myname.value);
Finding HTML elements Get reference to an HTML element Use window.document object getElementById() returns a reference to the first object with the specified ID getElementsByName() Returns an array of objects with the specified NAME attribute getElementsByTagName() Returns a collection of objects with the specified type (ie DIV, SPAN, TABLE, etc)
innerHTML Change the content of HTML element Read and Write property Cornerstone of AJAX Elements must have opening and closing tags: <p></p> <div></div> but not <img /> document.getElementById(‘myId’).innerHTML = “some new text”;
setAttribute Apply HTML attributes with JavaScript object.setAttribute(sName, vValue [, iFlags]) var myEl = document.getElementById('info_area'); myEl.setAttribute(&quot;class&quot;, &quot;hoverClass&quot;);
createElement / appendChild Allow you to insert HTML into the DOM Faster than adding with innerHTML Text nodes are immutable var myDiv = document.createElement('div'); myDiv.setAttribute(&quot;class&quot;, &quot;hoverClass2&quot;); var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv);
Other ways to create elements Four ways to do it node.cloneNode(bool)  – creates a copy of a node.. and depending on the bool.. copies contents too. document.createElement(el)  creates a new element node document.createTextNode(txt)  creates new text node el.innerHTML  – Create elements in text and add to the DOM that way. Frowned upon.. not always useful. Can be slow.
Adding/Removing Nodes in the Document node.removeChild(oldNode)  removes the child  oldNode  from  node node.appendChild(newNode)  adds  newNode  as a new (last) child node to  node node.insertBefore(newNode, oldNode)  inserts  newNode  as a new child node of  node  before  oldNode node.replaceChild(newNode, oldNode)  replaces the child node  oldNode  of  node  with  newNode
DOM Navigation node.firstChild Get the first element of the child array same as childNodes[0] node.childNodes Returns collection  of all nodes belonging to that node.. 1 st  level only. node.parentNode Returns the element that this node belongs to node.nextSibling Returns the next sibling belonging to this elements parent node.previousSibling Returns the earlier sibling belonging to this elements parent chaining: myNode.childNodes[0].childNodes[2].parentNode.nextSibling.previousSibling;
firstChild & Firefox Firefox considers text to be nodes when you think about it, this is correct but its not that convenient whitespace matters <table><tr><td></td></tr></table> <table> <tr> <td></td> </tr> </table> =
Exercise 1 – DOM Manipulation Use JavaScript and the DOM to create this document: Get optional application template at: http://www.nitobi.com/gwt/ex1.zip Don’t worry about styling
Exercise 1 – Possible Solution InsertDOM = function() { var myDiv = document.createElement('div'); var myHeading = document.createElement('h2'); myHeading.innerHTML = &quot;Customer Profile&quot;; var myP1 = document.createElement('p'); myP1.innerHTML = &quot;Jimmy Smith&quot;; var myDiv2 = document.createElement('div'); myDiv2.innerHTML = &quot;Jimmy is married with 2 kids and likes to Golf. Favorite beer is Molson Export.&quot;; // Here we asseble everything into one node myDiv.appendChild(myHeading); myDiv.appendChild(myP1); myDiv.appendChild(myDiv2); var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv); }
Modifying Style Attributes Get a reference to the style rule Modify an attribute: var myStyle = myElement.style; myStyle.backgroundColor = ‘#ffff00’; // yellow
DOM Stylesheet (1/2) Lets you step through each rule in each stylesheet Change selectors Read/write styles Add new rules Affect several elements at same time document.styleSheets collection contains all cssRules href other stuff
DOM Stylesheet (2/2) To find and change a class loop through all stylesheets look at the selectorText modify your style when you’ve found it if (myRules[k].selectorText == '.specialDiv') { myRules[k].style.position = 'absolute'; myRules[k].style.top = '100px'; myRules[k].style.left = '100px'; }
Cross Browser Alert! In FF/Safari you look for cssRules In IE you look for rules var myRules = (mySheets[i].rules || mySheets[i].cssRules);
ADVANCED JAVASCRIPT Threading
Threading Model JavaScript is single-threaded Doc parsing stops when scripts are embedded Browser stops responding to input when event handlers are executed Its possible to mimic multi-threading
Pseudo-threading in JavaScript Use the timer object to trigger events and JavaScript processing setTimeout setInterval Hypothetical animation
Initiate a timer Do the work Stop the thread A Simple Thread myGlobalReference = setTimeout(function() {drawObject(50)}, 50); drawObject = function(x) { // do some calculation or move an object a few pixels   myGlobalReference  = setTimeout(function() {drawObject(x+1)}, 50); } clearTimeout(myGlobalReference);
ADVANCED JAVASCRIPT JavaScript & DHTML
CSS for DHTML Key to dynamic HTML is modifying CSS with JS Attribute(s) Description position The type of positioning applied to an element top,left The position from the top left corner of the parent width,height Size of the element z-index Stacking order.. the 3 rd  dimension display Whether or not the element is rendered at all visibility Whether or not the element is visible overflow What to do with overflow content opacity How opaque or translucent an element is.. CSS3 attribute. IE has alternative
The KEY to DHTML Absolute positioning element.style.position = ‘absolute’ class { position: absolute; } Other options: relative  positioning – position is adjusted relative to its position in the normal flow fixed  positioning – relative to the browser window.  NO IE6
Position something with JS Get the element Set positioning (you could and shouldalso do this with a class). Set coordinates myElement = document.getElementById(‘myEL’); myElement.style.position = ‘absolute’; myElement.style.left = ‘20px’; myElement.style.top = ‘100px’;
Exercise 2 – Animation & Threading Animate a box resizing itself from 100px / 100px to 300 px / 300 px over several seconds Get optional application template at: http://www.nitobi.com/gwt/ex2.zip
Exercise 2 – Possible Solution AnimateDOMWithThread = function() { var myDiv = document.createElement('div'); myDiv.style.backgroundColor = &quot;#FFFF00&quot;; myDiv.style.width = &quot;100px&quot;; myDiv.style.height = &quot;100px&quot;; myDiv.innerHTML = &quot;Some text&quot;; var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv); window.myAnimObj = setTimeout(function() {animateBox(myDiv,100, 100)}, 20); } animateBox = function(myBox, w, h) { myBox.style.width = w + 'px'; myBox.style.height = h + 'px'; var neww = w+1; var newh = h+1; if ((neww <= 300) || (newh <= 300)) window.myAnimObj = setTimeout(function() {animateBox(myBox,neww,newh)}, 20); } Absolute positioning not required
Part 3 More Advanced
ADVANCED JAVASCRIPT Object Oriented Programming
Object Oriented JavaScript JavaScript is a prototypal language Class-based OO programming can be achieved Java JavaScript Strongly Typed Loosely Typed Static Dynamic Classical Prototypical Classes Functions Constructors Functions Methods Functions
Functions are Objects Too Important function methods: call(scope, arg1, arg2 …); apply(scope, [arg1, arg2 …]); caller Call and apply used to dynamically execute a function in arbitrary scope
Using Call function showLength() { alert(this.length); } showLength.call(new Array(10)); // Alerts 10! “ this” refers to the new Array
First, a review of an object This is an object Person = function(fn, ln) {}
Public Members Use this keyword Person = function(fn, ln) { this.firstName = fn; this.lastName = ln; } Person.prototype.getFullName = function() { return this.firstName + “ “ + this.lastName; } var a = new Person(“Alex”, “White”); console.log(a.firstName) // “Alex”
Private Members Local scope variables. Only accessible from within the constructor Person = function(fn, ln) { var firstName = fn; var lastName = ln; var getFullName = function() { return firstName + “ “ + lastName; } }
Privileged Members getFullName creates closure and therefor  exposes private vars through a getter(); Person = function(fn, ln) { var firstName = fn; var lastName = ln; this.getFullName = function() { return firstName + &quot; &quot; + lastName; } }
Classical JavaScript A Function() is a constructor Can use  new  keyword to instantiate to create new instances (copy). Use  this  to add instance methods and properties Person = function() { } var john = new Person(); Person = function() { this.age = 12; }
Basic Non-prototypal Class Start with a rectangle: Create an instance: Innefficient, memory hungry, inflexible Rectangle = function(w, h) { this.width = w; this.height = h; this.area = function() {return this.width*this.height;} } var r = New Rectangle(10,20); var a = r.area();  // 200;
Classical JavaScript Use “prototype” keyword to define instance properties and methods Same result different approach Rectangle = function(w, h) { this.width = w; this.height = h; } Rectangle.prototype.area = function() { return this.width*this.height; } var r = New Rectangle(10,20); var a = r.area();  // 200;
Another Advantage – Change the class Modify the prototype to add functionality to all instances of that prototype <!-- … --> Rectangle.prototype.widthSquared = function() { return this.width*this.width; } // var r = New Rectangle(10,20);  -- OUR OLD Rectangle OBJECT var ws = r.widthSquared();  // 100;
Classical Inheritance The simple approach PositionedRectangle = function(x,y,w,h) { Rectangle.call(this,w,h); // Now we store the left and right coords this.x = x; this.y = y; } PositionedRectangle.prototype = new Rectangle();
Inheritance – Simple Approach Why this might be bad Explicit reference to Rectangle in the constructor – brittle Constructor assigned to prototype – potentially brittle at compile-time if DOM is being drawn PositionedRectangle = function(x,y,w,h) { Rectangle.call(this,w,h); <!-- … --> PositionedRectangle.prototype = new Rectangle(); Will still work in most cases
Inheritance Function extend = function(subClass, baseClass) { function inheritance() {}; inheritance.prototype = baseClass.prototype; subClass.prototype = new inheritance(); subClass.baseConstructor = baseClass; if (baseClass.base) { baseClass.prototype.base = baseClass.base; } subClass.base = baseClass.prototype; } Customer = function (firstName, lastName) { Customer.baseConstructor.call(this, firstName, lastName); this.balance = 0; } Customer.prototype.getFullName = function() { Customer.base.getFullName.call(this); } extend(Customer, Person); remove compile-time constructor execution base constructor pointer base method pointers
More on the many ways to Inherit http://truecode.blogspot.com/2006/08/object-oriented-super-class-method.html Douglas Crockford – my hero http://www.crockford.com/javascript/inheritance.html
Classical Interfaces - Mixins No compilation in JavaScript so interfaces are tough Need to rely on mutability of JavaScript objects or “mixins” var customer1 = new Customer(); var customer2 = new Customer(); customer1.pay = function(amout) { this.balance -= amount; } customer1.pay(); customer2.pay(); // ERROR!
Classical Interfaces - Mixins Mutate classes at runtime Think of the implications for AOP var customer1 = new Customer(); var customer2 = new Customer(); Customer.prototype.pay = function(amount) { this.balance -= amount; } customer1.pay(); customer2.pay(); var f = Customer.oldFunction Customer.oldFunction = function() { f.call(this); somethingElse(); }
ADVANCED JAVASCRIPT Ajax
Ajax Versus Traditional
XMLHttpRequest The core of Ajax var xhr = null; try { xhr = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;); } catch(e) { xhr = new XMLHttpRequest(); } xhr.open(&quot;GET&quot;, &quot;http://www.example.com/myResource&quot;, false); xhr.send(null); showResult(xhr); Async = false IE 6 and 7 Everybody Else
XHR Factory Use Factory pattern to create XHR objects in a cross-browser manner xhrFactory = { create: function() { try { xhr = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;); } cstch(e) { xhr = new XMLHttpRequest(); } return xhr; } } var xhr = xhrFactory.create();
Synchronous Requests Simplest case However, JavaScript thread is locked! var xhr = xhrFactory.create(); xhr.open(&quot;GET&quot;, “http://www.example.com/resource”, false); var response = xhr.send(null); Async = false
Asynchronous Requests Use async requests to prevent locking the JavaScript thread xhr.open(&quot;GET&quot;, “http://www.example.com/resource”, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { //  deal with the response } } } Async = true Regular HTTP status code
Request Types GET POST xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); xhr.open(“POST”, “http://www.example.com/resource”, false); var response = xhr.send(“firstName=john&lastName=doe”);
Data Types POST data to the server as either XML or form encoded data Use XHR setRequestHeader() method xhr.setRequestHeader(&quot;Content-Type&quot;,&quot;text/xml&quot;); xhr.setRequestHeader(&quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;); XML Form data
Response Data We can expect the response from the server as XML, JSON, HTML or text xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); alert(response.responseXml); // Should show a [Document] for XML response alert(response.responseText); // Should show the XML, JSON, or HTML data Make sure you set the response type on the server too!
What Type of Response? XML Good for Web Services and XML RPC A bit more work on the client.. browser differences JSON Easy, fast HTML No rendering logic on client bandwidth considerations Just yse what you prefer…..
XML Response Various ways of dealing with XML data XML DOM – most compatible XPath – fast and easy XSLT – not supported everywhere xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = “”; var customers = response.responseXml.getElementsByTagName(“customer”); for (var i=0; i<customers.length; i++) { var customer = customers[i]; html += “<div>”+customer.childNodes[0].nodeValue+”</div>”; html += “<div>”+customer.childNodes[1].nodeValue+”</div>”; } alert(html);
JSON Response Need to instantiate the data into JavaScript objects xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = “”; var customers = eval(“(“+response.responseText+”)”); // OR eval(“a = “ + response.responseText); for (var i=0; i<customers.length; i++) { var customer = customers[i]; html += “<div>”+customer.firstName+”</div>”; html += “<div>”+customer.lastName+”</div>”; } alert(html);
HTML Response Take the HTML from the server and put it into the web page DOM xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = response.responseText alert(html);
Cross-Domain XHR Create <script> element dynamically Response from server includes JavaScript and calls a callback function Called JSONP or XMLP var customers = [{firstName:”John”,lastName:”Doe”}] myCallback(customers); var script = document.createElement(“script”); script.src = “http://www.example.com/resource?callback=myCallback”; document.getElementsByTagName(“head”)[0].appendChild(script); Dynamically generated function call
Cross-Domain JSONP Security There are serious security risks with JSON or XMLP Also serious risks with JSON in general Return JSON data in comments to prevent non XHR access <!-- [{firstName:”John”,lastName:”Doe”}] -->
ADVANCED JAVASCRIPT DOM Events
DOM Events Native Event object contains information about the event Two approaches to defining events: Inline Unobtrusive Unobtrusive approach requires cross-browser event attachment
Native Events Document load, unload, resize, scroll Mouse mouseover, mouseout, mouseup, mousedown, click Key keydown, keyup, keypress Forms focus, blur, change, keydown, keyup, keypress
onload Event Need the page JavaScript to execute as soon as possible onload waits for all images etc to load if (document.addEventListener) document.addEventListener('DOMContentLoaded', init, false); <!--[if IE]><script defer src=&quot;ie_onload.js&quot;></script><![endif]--> window.onload = init; Firefox Internet Explorer The rest
Inline Events Most simple event attachment What about separating our control from our view? <div onmouseover=“swapColor(event)” onmouseout=“swapColor(event)”></div>
DOM Event Decoration Attach event handlers to DOM nodes through JavaScript This can create memory leaks when using anonymous functions var domNode = document.getElementById(“myNode”); domNode.onmouseover = highlight; var domNode = document.getElementById(“myNode”); domNode.onmouseover = function() { domNode.style.color = ‘red’;}; Function pointer Most common way of creating memory leaks in IE
DOM Event Decoration var domNode = document.getElementById(“myNode”); domNode.attachEvent(“onmouseover”, highlight); W3C - Firefox var domNode = document.getElementById(“myNode”); domNode.addEventListener(“mouseover”, hightlight, false); Internet Explorer Capture Function pointer Prefixed with “on”
Event Object Internet Explorer W3C document.documentElement.clientHeight clientX / Y clientX / Y, pageX / Y clientX / Y returns the event coordinates without the document scroll position taken into account, whereas pageX / Y does take scrolling into account. N/A currentTarget The HTML element to which the event handler was attached. keyCode, altKey, ctrlKey, shiftKey keyCode, altKey, ctrlKey, shiftKey Various key event modifiers to check if ctrlKey, shiftKey ctrlKey, shiftKey the Shift or Ctrl key are pressed. srcElement target The HTML element on which the event actually took place. Both properties  are supported in Opera and Safari. type type The event type without the “on” prefix. fromElement / toElement relatedTarget from is used only for mouseover and mouseout events. Both properties are supported in Opera and Safari
Event Questions How do you access the Event object? What does “this” refer to in the event handler function?
Event Object Passed as argument to event handler in W3C model and as a global in IE function swapColor(evt) { } W3C function swapColor() { var evt = window.event; } Internet Explorer
Handler Execution Scope “ this” is the element that handled the event (W3C) or the window (IE) function swapColor(evt) { this.style.color = “#FF0000”; } W3C function swapColor() { window.event.srcElement.style.color } Internet Explorer
Cross-Browser Event Façade Make Internet Explorer look like W3C eventManager = {}; // Singleton object eventManager.attachEvent = function(elem, type, handler, capture) { // Browser checking for IE vs W3C compliant browser if (elem.attachEvent) { // Create two expando properties with function references elem[‘evt_' + type] = function() { handler.call(elem); }; // Attach one of our expando function references to the event elem.attachEvent('on'+type, elem[‘evt_' + type]); // Set the capture if it was specified if (capture) elem.setCapture(true); } else if (elem.addEventListener) { elem.addEventListener(type, handler, capture); } } IE W3C Sets scope of “this” Event type “mouseover”, etc Detects IE
Event Flow Events have two phases Events are first captured and propagate from the <body> to the target element Event then bubbles back up from the target element to the <body> Capture is  very  different in IE and W3C but important nonetheless
Event Flow <body> <div> </div> <a onclick=“handler()”></a> </body> Bubble Capture
Event Creation Programmatic event creation if (window.attachEvent) // Internet Explorer { element.fireEvent('on'+evtName); } else { // create and init a new event var newEvent = document.createEvent(evtType); newEvent.initKeyEvent(evtName, true, true, document.defaultView, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode); // dispatch new event element.dispatchEvent(newEvent); }
Exercise 3 – OO JavaScript (if time) Create the following objects: Person class age name height Customer class account balance inherits from Person Put at least 1 prototype method on each class.  Create a few customers Get optional application template at: http://www.nitobi.com/gwt/ex3.zip
Exercise 3 – Possible Solution Person = function(fname, lname, age) { this.firstName = fname; this.lastName = lname; this.age = age; } Person.prototype.getFullName = function() { return this.firstName + &quot; &quot; + this.lastName; } Customer = function(fname, lname, age, balance) { this.balance = balance; Person.call(this,fname, lname, age); } Customer.prototype = new Person(); Customer.prototype.getBalance = function() { return '$' + this.balance;} setupCustomers = function() { var cust1 = new Customer(&quot;John&quot;, &quot;Smith&quot;, 24, 233.23); console.log(cust1.getFullName()); console.log(cust1.getBalance()); }
Finito Questions?

Ajax and JavaScript Bootcamp

  • 1.
  • 2.
    A bit aboutme Development: Ruby/Rails, PHP, Coldfusion, Some ASP.NET, C++ back in the day, Turbo Pascal, etc, etc Design Enterprise Ajax Recent Projects: CompleteUI Component Suite Nintendo RobotReplay SayZu
  • 3.
    About Nitobi RichInternet Application development. Off-the-shelf Ajax UI components Cross Platform Java ASP.NET PHP Coldfusion Classic ASP Ruby on Rails
  • 4.
    Bootcamp Goals Developpractical understanding of ECMAScript Actual coding Not too deep, not too shallow Remove mystery behind Rich Internet Applications Expose the trouble spots
  • 5.
    Today’s Format Part1 (Basics) Lexical Structure Datatypes Variables Operators, Expressions & Statements 10 minute break Part 2 (More Advanced) Debugging Basic DOM Exercise 1 Threading JavaScript & DHTML Exercise 2 10 minute break Part 3 (More Advanced) Object Oriented Programming Ajax (XHR) DOM Events Exercise 3
  • 6.
    JavaScript Gotcha’s Theseslides will highlight Some browser-specific difficulty General wierdness Something else
  • 7.
    IDE’s - PCAptana Studio Integrated Debugging (IE/FF) Library Support AIR, Rails, PHP, etc SVN Support Visual Studio Integrated debugging Great Project Support Intellisense JSEclipse Text Editor Notepad++, Textedit Dreamweaver - MAC Textmate project support syntax highlighting snippets Aptana JSEclipse Text Editor’s I recommend
  • 8.
    Part 1 TheBasics
  • 9.
    Essence of JavaScript(1/2) JavaScript != Java JavaScript != Simple
  • 10.
    Essence of JavaScript(2/2) ECMAScript Dynamic Client-side Prototype based Associative arrays Weakly typed Obj.x = 10; Obj[“x”] = 10;
  • 11.
    Understanding the Client-ServerBoundary JavaScript has no secrets Client is unknown Dynamic – eval() Cross-site communication restricted
  • 12.
    The impact ofBrowsers Sandbox implementation errors Minor implementation differences JavaScript Cascading Style Sheets Layout Supported media types
  • 13.
    What Can youdo in JavaScript? Draw boxes, images, and text Open and close windows Animate on-screen contents Modify the document Communicate with the server Talk to Java, Flash, Silverlight Snoop on the user.. record what they do. Read the mouse/keyboard
  • 14.
    What it can’tdo (1/2) Can’t open files Write to the file system Talk directly to hardware Read freely from memory Perform general networking open a socket etc Do Ajax across domains “ Security Sandbox”
  • 15.
    What it can’tdo (2/2) Can’t close windows willy-nilly Hide the destination of links Open windows that are too small Set the value of FileUpload fields Rotate graphics Make sound
  • 16.
  • 17.
    Lexical Structure AllUnicode, all the time UTF-16 can represent most languages String operators respect encoding Case Sensitive (Most of the time) >>> var A = 1; >>> var a = 2; >>> a 2 >>> A 1 var a = 0; WHILE(a <= 2) { a+=1; }; var a = 0; while (a <= 2) { a+=1; };
  • 18.
    Lexical Structure Whitespaceignored Optional semicolons var a = 2; if (a == 2) console.log('yep'); console.log('Carrying on'); var a = 2; if (a == 2) console.log('yep'); console.log('Carrying on'); a = 3 b = 4 Will be executed as a = 3; b = 4; return true; Will be executed as return; true; But you probably meant return true;
  • 19.
    Whitespace & SemicolonsFilesizes reduced by removing whitespace Missing semicolons can cause JS errors a = 3 b = 4 Will be become a = 3 b = 4 No Worky
  • 20.
    Lexical Structure CommentsLiterals // This is a single-line comment. /* This is also a comment */ // here is another comment /* * This is a multiline comment * */ 12 // The number 12 “ hello world” // A string of text ‘ hey now’ // Another string true // A boolean value /javascript/gi // A “regular expression” literal Null // Absense of an object
  • 21.
    Lexical Structure ObjectLiterals Identifiers (Variables) { name: “Alexei”, weight: 160 } // An object initializer [23,345,12,341,2] // An array initializer [{a:2},{a:56,name:’Buck’},{c:65}] // An array of objects.. a my_variable_name v382 _something $ $fgj 34fg .vgf
  • 22.
    Lexical Structure ReservedWords Reserved & Special break case catch continue default delete do else false finally for function if in instanceof new null return switch this throw true try typeof var void while with abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile A biggie
  • 23.
    Lexical Structure Wordsto avoid arguments Array Boolean console Date decodeURI decodeURIComponent encodeURI Error escape eval EvalError Function Infinity isFinite isNan Math NaN Number Object parseFloat parseInt RangeError ReferenceError RegExp String SyntaxError TypeError undefined unescape URIError A biggie
  • 24.
  • 25.
    Datatypes Number StringBoolean null undefined Objects Arrays Functions Dates RegExp Error Primitive types Reference types
  • 26.
    Datatypes – UsefulInformation Numbers All floating point 64 bit (huge) (+/-) 1.7976931348623157x10 308 Small: 1.474334E-32 Hexadecimal Literals 0xff , 0xCAFE911 Numeric Constants Infinity, NaN, Number.MAX_VALUE, Number.NEGATIVE_INFINITY
  • 27.
    Datatypes – UsefulInformation Strings Modern ECMAScript implementations support Unicode Escape sequences: ‘ You\’re always saying what can\’t be done’ \u for unicode (eg: \u03c0 for  ) Concatenation Myname = first_name + ‘ danger ‘ + last_name; Strings are objects Myname.length, Myname.indexOf() Convert numbers to strings Msg = 100 + ‘’; Msg = String(100); Msg = 100.toString(); Strings to Numbers Myval = parseInt(“3 people”) // 3
  • 28.
    Datatypes – UsefulInformation Boolean Values Often the result of comparisons (a == 4) Used in control structures: Type conversions are often automatic Numeric : true == 1, false == 0 Type conversion is easy if (a == 4) b = b + 1; else b = b – 1; c = true + true // 2 d = true + ‘’ // ‘true’ var x = Boolean(1); // true a = 1; var y = !!a; // true
  • 29.
    Datatypes – functionsFunctions can be stored in variables, arrays, etc. Can define lambda or anonymous functions function square(x) { // function is called square, expects 1 argument return x*x; // the function squares its arg and returns result } // function ends here function square(x) { return x*x; } var square = function(x){ return x*x; } =
  • 30.
    Datatypes – objectsJavaScript has built-in objects Objects are associative arrays Invoked using new keyword document.forms document.images window.innerWidth window.scrollY document.forms document.images document[“forms”] document[“images”] = var a = new Object(); var now = new Date(); var pattern = new RegExp( “\\sjava\\s ”, “i”) a.x = 1.1; a.y = 344;
  • 31.
    Datatypes – objectsObject literals Comma-separated list of name-value pairs AKA JSON (JavaScript Object Notation) var vertex = { x:3.2, y:13.2, z:64.3 }; var user = { &quot;fullName&quot;: &quot;John Smith&quot;, &quot;address&quot;: { &quot;streetAddress&quot;: &quot;21 2nd Street&quot;, &quot;city&quot;: &quot;New York&quot;, &quot;postalCode&quot;: 10021 }, &quot;phoneNumbers&quot;: [ &quot;212 732-1234&quot;, &quot;646 123-4567&quot; ] }
  • 32.
    Datatypes – objectsObject conversion: Does an object exist? Objects as strings if (myObj) { // Do something } a = {b:34,t:4} b = a + “” // “[object Object]”
  • 33.
    Datatypes - arraysA collection of values, like an object Can contain any type of JS data var a = new Array(1.1, “something”, true, {x:43,y:34}); var b = new Array(); b[0] = 1.1; b[1] = “something”; b[2] = true; b[3] = {x:43,y:34}; var c = new Array(20);
  • 34.
    Datatypes - arraysArray literals Sparse arrays Array length Searching var a = [1.2, “something”, true, {x:33,y:34}]; var a = [1,,,,5]; a.length var array = [2, 5, 9]; var index = array.indexOf(5); // index is 1 index = array.indexOf(7); // index is -1
  • 35.
    Datatypes – null& undefined null Indicates no value No object Converts to false in Boolean context (if (null)) undefined Not null Used when a variable is declared but has no value Comparing the two null == undefined null !== undefined
  • 36.
    Datatypes - datesNot a fundamental type, but a class of object Easily use local or GMT time. Date math, and type conversion var now = new Date(); // create an object holding current // date and time var xmas = new Date(2007,11,25); xmas.setFullYear(xmas.getFullYear() + 1); // Next christmas var weekday = xmas.getDay(); // Day of week console.log(“Today is: “ + now.toLocaleString()); // Convert to string More on this Later!
  • 37.
    Datatypes – regularexpressions Pattern matching Search and replace Use the string method replace /^NITOBI/ /[1-9][0-9]*/ /\bnitobi\b/i Mystr.replace(/\bnitobi\b/I, “NITOBI”); // capitalize all instances // of NITOBI.
  • 38.
    Datatypes – errorobjects Represents a runtime error Besides the base Error, there are six other core error types in JavaScript EvalError RangeError ReferenceError SyntaxError TypeError URIError Contains the following properties: constructor message name prototype try { throw new Error(&quot;Whoops!&quot;); } catch (e) { alert(e.name + &quot;: &quot; + e.message); } More on this Later!
  • 39.
    Comparing Types Equalityvs Identity Inspecting an identifier (typeof) var a =1; var b = true; a == true; // true a === true; // false b === true; // true a !== true; // true typeof(a); // “number” typeof(b); // “boolean”
  • 40.
    Value vs Reference3 ways to manipulate data values Copy it Pass it as an argument Compare it 2 ways to manipulate variables By value By reference
  • 41.
    Value vsReference // copying by Value var a = 1; var b = a; // copy by value.. Two distinct values now // passing an argument by Value function add_to_sum(sum, x) { sum = sum + x; // this only changes the internal } // copy of x add_to_sum(a,1); if (b == 1) b = 2; // b is a distinct numeric value // a is still 1, and b is 2 Won’t actually do anything
  • 42.
    Value vs Reference // copying by reference var xmas = new Date(2007, 11, 25); var gift_day = xmas; // both variables refer to the same object gift_day.setDate(26); // we’ve now changed both variables function add_to_sum(sum, x) { sum[0] = sum[0] + x; sum[1] = sum[1] + x; sum[2] = sum[1] + x; } (xmas == gift_day) // this is true still xmas.getDate(); // returns 26 not 25 var newdate1 = new Date(2007,10,10); var newdate2 = new Date(2007,10,10); (newdate1 == newdate2) // this is false Permanently changes ‘sum’ in global context Note: Strings are compared by value
  • 43.
  • 44.
    Typing JavaScript isweakly typed A variable can hold a value of any type at any time i = 10; i = “ten”; OK, no problem.
  • 45.
    Variable Declaration Explicitdeclaration not required Implicit declaration has scope consequences Repeated declaration OK too. var i; var sum; var i, sum; var message = “hello”; var i = 0, j = 0, k = 43; var i = 1; // 1 var i = 2; // 2
  • 46.
    Variable Scope Global– available everywhere Local – available within a function Local > Global var scope= “global”; function checkscope() { var scope = “local”; console.log(scope); // prints ‘local’; } console.log(scope); // prints ‘global’; Note: No Block Scope except SWITCH & WITH
  • 47.
    Variable Scope varx = 1; function f() { } function g() { }
  • 48.
    Garbage Collection Memoryallocated and deallocated automatically Interpreter detects when allocated memory is unreachable var s = “hello”; // allocate some mem var u = s.toUpperCase(); // copy the value to a new string s = u; // “hello” now unreachable and is destroyed
  • 49.
    Explorer Memory LeaksCircular references can cause memory leaks. Object A Object B Object A References B Object B References A
  • 50.
    JAVASCRIPT BASICS Operators,Expressions & Statements
  • 51.
    Operators Operator Operandtype(s) Operation performed . Object, identifier Property access [ ] Array, integer Array index ! Boolean Logical complement == Any Equality === Any Identity && Booleans Logical AND || Booleans Logical OR ?: Booleans, any, any Conditional operator , Any Multiple evaluation
  • 52.
    Assignment with OperationOperator Example Equivalent += a += b a = a + b -= a -= b a = a – b *= a *= b a = a * b /= a /= b a = a / b %= a %= b a = a % b <<= a <<= b a = a <<b >>= a >>= b a = a >>b >>>= a >>>= b a = a >>> b &= a &= b a = a & b |= a |= b a = a | b ^= a ^= b a = a ^ b
  • 53.
    Conditional Operator (?:)Ternary operator (three operands) is equivalent to.. Fast, and compact. greeting = “hello “ + (username != null ? username : “there”); greeting = “hello “; if (username != null) greeting += username; else greeting += “there”; Don’t rely on a compiler for code optimization
  • 54.
    Notes about StatementsBrackets around expressions are required Single statements do not require curly-braces Whitespace ignored if ( expression ) statement if ( expression ) statement if ( expression ) { statement statement } if ( expression ) statement else statement
  • 55.
    If / elseif Execute multiple pieces of conditional code if (n == 1) { // Execute code block 1 } else if (n == 2) { // Execute code block 2 } else if (n == 3) { // Execute block 3 } else { // if all else fails, do this } if (n == 1) { // block 1 } else { if (n == 2) { // block 2 } else { if (n == 3) { // block 3 } else { // do this } } } Equivilent
  • 56.
    Switch Better ifyou are just checking the same var over and over switch(n) { case 1: // start here if n == 1 // code block 1 break; case 2: // code block 2 break; case 3: // code block 3 break; default: // if all else fails… // code block 4 break; } Only use constants in CASE expressions
  • 57.
    while, do/while varcount = 0; while (count < 10) { console.log(count); count++; } var count = 0; do { console.log(count); count++; } while (count < 10) Will execute at least once
  • 58.
    for for( initialize ; test ; increment ) statement for (var count = 0; count < 10; count++) console.log(count); for( variable in object ) statement var o = {x:1, y:2, z:3} var a = new Array(); var I = 0; for(a[i++] in o) {} Curly braces {} are not required if just one statement Copies the object “o” to the array “a” Not all properties are enumerable!
  • 59.
    Performance Pitfall Array.lengthis expensive better: best: for (var count = 0; count < myarray.length; count++) console.log(count); for (var count = 0, mylen = myarray.length; count < mylen; count++) console.log(count); for (var count = myarray.length-1; count > 0; count--) console.log(count); re-calculated EVERY TIME --SLOW-- !!
  • 60.
    labels Any statementmay be labeled Usually just used for loops Used for breaking and continuing myloop: while(something != null) { // code block }
  • 61.
    break Causes theinnermost enclosing loop or switch to exit. Can be combined with labels break; outerloop: for(var i = 0; i < 10; i++) { innerloop: for(var j = 0; j < 10; j++) { if (j > 3) break; // quit innermost loop if (i == 2) break innerloop; if (i == 4) break outerloop; } }
  • 62.
    continue Like break..but just skips to the next iteration of the current loop Can be used with labels for(i = 0; i < data.length; i++) { if (data[i] == null) continue; total += data[i]; }
  • 63.
    try/catch/finally/throw Create anexception Custom exceptions try { 43534987yhfh // clearly an error } catch(myerr) { console.log(myerr); } finally { //code block } try { throw(“User entered invalid data..”); } catch(myerr) { console.log(myerr); } finally { //code block } always executes regardless of what happens in catch() or try() Will write “Something bad happened..”
  • 64.
    with Code blockthat modifies the scope chain Generally avoided. slow some unexpected behaviors (with init’d vars) with(frames[1].document.forms[0]) { // access form elements directly here. eg: name.value = “something”; address.value = “someplace”; email.value = “me@home.com”; }
  • 65.
    ; (empty) Hasno effect.. but can be useful. var o = {x:1, y:2, z:3} var a = new Array(); var I = 0; for(a[i++] in o) ;
  • 66.
    Part 2 MoreAdvanced
  • 67.
  • 68.
    Firebug Free Firefoxplugin (http://www.getfirebug.com) Shows you 2 important things: What’s going on in your page when it loads & After it loads Advanced features Code profiling CSS debugging DOM Inspection JavaScript breakpoints and step-through XHR Debugging JSON Object Inspection Integration with Aptana
  • 69.
    MS Script DebuggerStep over, into Console window Not much else Visual Studio better (if you have it)
  • 70.
    IE Developer ToolbarUseful for debugging CSS in IE Lacks many of the features in Firebug Convenient cache clearing Change CSS attributes on the fly Inspect Cache DOM browsing
  • 71.
    Firebug Lite JavaScriptextension for NON-Firefox browsers Mimics some of the console features of Firebug Evaluate JavaScript in-line Makes cross-browser testing a lot easier.
  • 72.
    Drosera - SafariWebKit JS debugger Code stepping DOM Inspection Mac-only
  • 73.
  • 74.
    JavaScript in theBrowser JavaScript should be unobtrusive Separation of concerns Keep it away from markup Modularize it Degrade gracefully* <html> <head> <script type=&quot;text/javascript&quot; src=&quot;code.js”></script> </head> <body> </body> </html> Sometimes this is real hard
  • 75.
    Window window isglobal context literally means the browser window global variables can be referred to as window.variable Document object is a member Contains a hierarchical representation of document. Contains window info Geometry scroll position window.innerHeight window.innerWidth
  • 76.
    Window Geometry BrowserDifferences Browser window.innerHeight document.body.clientHeight document.documentElement.clientHeight Opera 9.5+ strict window document window Opera 9.5+ quirks window window document Opera 7-9.2 window window document Opera 6 window window N/A Mozilla strict window document window Mozilla quirks window window document KHTML window document document Safari window document document iCab 3 window document document iCab 2 window window N/A IE 6+ strict N/A document window IE 5-7 quirks N/A window 0 IE 4 N/A window N/A ICEbrowser window window document Tkhtml Hv3 window window document Netscape 4 window N/A N/A
  • 77.
    onload Event Handleronload fires after all HTML, CSS, Images, and JS is downloaded to the client. At this time, all JavaScript functions and objects part of the window object have been registered. <html> <head> <script type=&quot;text/javascript&quot; src=&quot;code.js”></script> </head> <body onload=“myFunction()” > </body> </html>
  • 78.
    Document Object ModelTree-structure document elements, attributes, and text text nodes are immutable
  • 79.
    Form Objects, fields,etc Forms are held in a collection Elements accessible as an array or an object var myForm = document.forms[&quot;customerForm&quot;]; myForm = document.customerForm; for (var i = 0, j = myForm.length; i < j; i++) console.log(myForm[i].value); console.log(myForm.myname.value);
  • 80.
    Finding HTML elementsGet reference to an HTML element Use window.document object getElementById() returns a reference to the first object with the specified ID getElementsByName() Returns an array of objects with the specified NAME attribute getElementsByTagName() Returns a collection of objects with the specified type (ie DIV, SPAN, TABLE, etc)
  • 81.
    innerHTML Change thecontent of HTML element Read and Write property Cornerstone of AJAX Elements must have opening and closing tags: <p></p> <div></div> but not <img /> document.getElementById(‘myId’).innerHTML = “some new text”;
  • 82.
    setAttribute Apply HTMLattributes with JavaScript object.setAttribute(sName, vValue [, iFlags]) var myEl = document.getElementById('info_area'); myEl.setAttribute(&quot;class&quot;, &quot;hoverClass&quot;);
  • 83.
    createElement / appendChildAllow you to insert HTML into the DOM Faster than adding with innerHTML Text nodes are immutable var myDiv = document.createElement('div'); myDiv.setAttribute(&quot;class&quot;, &quot;hoverClass2&quot;); var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv);
  • 84.
    Other ways tocreate elements Four ways to do it node.cloneNode(bool) – creates a copy of a node.. and depending on the bool.. copies contents too. document.createElement(el) creates a new element node document.createTextNode(txt) creates new text node el.innerHTML – Create elements in text and add to the DOM that way. Frowned upon.. not always useful. Can be slow.
  • 85.
    Adding/Removing Nodes inthe Document node.removeChild(oldNode) removes the child oldNode from node node.appendChild(newNode) adds newNode as a new (last) child node to node node.insertBefore(newNode, oldNode) inserts newNode as a new child node of node before oldNode node.replaceChild(newNode, oldNode) replaces the child node oldNode of node with newNode
  • 86.
    DOM Navigation node.firstChildGet the first element of the child array same as childNodes[0] node.childNodes Returns collection of all nodes belonging to that node.. 1 st level only. node.parentNode Returns the element that this node belongs to node.nextSibling Returns the next sibling belonging to this elements parent node.previousSibling Returns the earlier sibling belonging to this elements parent chaining: myNode.childNodes[0].childNodes[2].parentNode.nextSibling.previousSibling;
  • 87.
    firstChild & FirefoxFirefox considers text to be nodes when you think about it, this is correct but its not that convenient whitespace matters <table><tr><td></td></tr></table> <table> <tr> <td></td> </tr> </table> =
  • 88.
    Exercise 1 –DOM Manipulation Use JavaScript and the DOM to create this document: Get optional application template at: http://www.nitobi.com/gwt/ex1.zip Don’t worry about styling
  • 89.
    Exercise 1 –Possible Solution InsertDOM = function() { var myDiv = document.createElement('div'); var myHeading = document.createElement('h2'); myHeading.innerHTML = &quot;Customer Profile&quot;; var myP1 = document.createElement('p'); myP1.innerHTML = &quot;Jimmy Smith&quot;; var myDiv2 = document.createElement('div'); myDiv2.innerHTML = &quot;Jimmy is married with 2 kids and likes to Golf. Favorite beer is Molson Export.&quot;; // Here we asseble everything into one node myDiv.appendChild(myHeading); myDiv.appendChild(myP1); myDiv.appendChild(myDiv2); var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv); }
  • 90.
    Modifying Style AttributesGet a reference to the style rule Modify an attribute: var myStyle = myElement.style; myStyle.backgroundColor = ‘#ffff00’; // yellow
  • 91.
    DOM Stylesheet (1/2)Lets you step through each rule in each stylesheet Change selectors Read/write styles Add new rules Affect several elements at same time document.styleSheets collection contains all cssRules href other stuff
  • 92.
    DOM Stylesheet (2/2)To find and change a class loop through all stylesheets look at the selectorText modify your style when you’ve found it if (myRules[k].selectorText == '.specialDiv') { myRules[k].style.position = 'absolute'; myRules[k].style.top = '100px'; myRules[k].style.left = '100px'; }
  • 93.
    Cross Browser Alert!In FF/Safari you look for cssRules In IE you look for rules var myRules = (mySheets[i].rules || mySheets[i].cssRules);
  • 94.
  • 95.
    Threading Model JavaScriptis single-threaded Doc parsing stops when scripts are embedded Browser stops responding to input when event handlers are executed Its possible to mimic multi-threading
  • 96.
    Pseudo-threading in JavaScriptUse the timer object to trigger events and JavaScript processing setTimeout setInterval Hypothetical animation
  • 97.
    Initiate a timerDo the work Stop the thread A Simple Thread myGlobalReference = setTimeout(function() {drawObject(50)}, 50); drawObject = function(x) { // do some calculation or move an object a few pixels myGlobalReference = setTimeout(function() {drawObject(x+1)}, 50); } clearTimeout(myGlobalReference);
  • 98.
  • 99.
    CSS for DHTMLKey to dynamic HTML is modifying CSS with JS Attribute(s) Description position The type of positioning applied to an element top,left The position from the top left corner of the parent width,height Size of the element z-index Stacking order.. the 3 rd dimension display Whether or not the element is rendered at all visibility Whether or not the element is visible overflow What to do with overflow content opacity How opaque or translucent an element is.. CSS3 attribute. IE has alternative
  • 100.
    The KEY toDHTML Absolute positioning element.style.position = ‘absolute’ class { position: absolute; } Other options: relative positioning – position is adjusted relative to its position in the normal flow fixed positioning – relative to the browser window. NO IE6
  • 101.
    Position something withJS Get the element Set positioning (you could and shouldalso do this with a class). Set coordinates myElement = document.getElementById(‘myEL’); myElement.style.position = ‘absolute’; myElement.style.left = ‘20px’; myElement.style.top = ‘100px’;
  • 102.
    Exercise 2 –Animation & Threading Animate a box resizing itself from 100px / 100px to 300 px / 300 px over several seconds Get optional application template at: http://www.nitobi.com/gwt/ex2.zip
  • 103.
    Exercise 2 –Possible Solution AnimateDOMWithThread = function() { var myDiv = document.createElement('div'); myDiv.style.backgroundColor = &quot;#FFFF00&quot;; myDiv.style.width = &quot;100px&quot;; myDiv.style.height = &quot;100px&quot;; myDiv.innerHTML = &quot;Some text&quot;; var body = document.getElementsByTagName('body')[0]; body.appendChild(myDiv); window.myAnimObj = setTimeout(function() {animateBox(myDiv,100, 100)}, 20); } animateBox = function(myBox, w, h) { myBox.style.width = w + 'px'; myBox.style.height = h + 'px'; var neww = w+1; var newh = h+1; if ((neww <= 300) || (newh <= 300)) window.myAnimObj = setTimeout(function() {animateBox(myBox,neww,newh)}, 20); } Absolute positioning not required
  • 104.
    Part 3 MoreAdvanced
  • 105.
    ADVANCED JAVASCRIPT ObjectOriented Programming
  • 106.
    Object Oriented JavaScriptJavaScript is a prototypal language Class-based OO programming can be achieved Java JavaScript Strongly Typed Loosely Typed Static Dynamic Classical Prototypical Classes Functions Constructors Functions Methods Functions
  • 107.
    Functions are ObjectsToo Important function methods: call(scope, arg1, arg2 …); apply(scope, [arg1, arg2 …]); caller Call and apply used to dynamically execute a function in arbitrary scope
  • 108.
    Using Call functionshowLength() { alert(this.length); } showLength.call(new Array(10)); // Alerts 10! “ this” refers to the new Array
  • 109.
    First, a reviewof an object This is an object Person = function(fn, ln) {}
  • 110.
    Public Members Usethis keyword Person = function(fn, ln) { this.firstName = fn; this.lastName = ln; } Person.prototype.getFullName = function() { return this.firstName + “ “ + this.lastName; } var a = new Person(“Alex”, “White”); console.log(a.firstName) // “Alex”
  • 111.
    Private Members Localscope variables. Only accessible from within the constructor Person = function(fn, ln) { var firstName = fn; var lastName = ln; var getFullName = function() { return firstName + “ “ + lastName; } }
  • 112.
    Privileged Members getFullNamecreates closure and therefor exposes private vars through a getter(); Person = function(fn, ln) { var firstName = fn; var lastName = ln; this.getFullName = function() { return firstName + &quot; &quot; + lastName; } }
  • 113.
    Classical JavaScript AFunction() is a constructor Can use new keyword to instantiate to create new instances (copy). Use this to add instance methods and properties Person = function() { } var john = new Person(); Person = function() { this.age = 12; }
  • 114.
    Basic Non-prototypal ClassStart with a rectangle: Create an instance: Innefficient, memory hungry, inflexible Rectangle = function(w, h) { this.width = w; this.height = h; this.area = function() {return this.width*this.height;} } var r = New Rectangle(10,20); var a = r.area(); // 200;
  • 115.
    Classical JavaScript Use“prototype” keyword to define instance properties and methods Same result different approach Rectangle = function(w, h) { this.width = w; this.height = h; } Rectangle.prototype.area = function() { return this.width*this.height; } var r = New Rectangle(10,20); var a = r.area(); // 200;
  • 116.
    Another Advantage –Change the class Modify the prototype to add functionality to all instances of that prototype <!-- … --> Rectangle.prototype.widthSquared = function() { return this.width*this.width; } // var r = New Rectangle(10,20); -- OUR OLD Rectangle OBJECT var ws = r.widthSquared(); // 100;
  • 117.
    Classical Inheritance Thesimple approach PositionedRectangle = function(x,y,w,h) { Rectangle.call(this,w,h); // Now we store the left and right coords this.x = x; this.y = y; } PositionedRectangle.prototype = new Rectangle();
  • 118.
    Inheritance – SimpleApproach Why this might be bad Explicit reference to Rectangle in the constructor – brittle Constructor assigned to prototype – potentially brittle at compile-time if DOM is being drawn PositionedRectangle = function(x,y,w,h) { Rectangle.call(this,w,h); <!-- … --> PositionedRectangle.prototype = new Rectangle(); Will still work in most cases
  • 119.
    Inheritance Function extend= function(subClass, baseClass) { function inheritance() {}; inheritance.prototype = baseClass.prototype; subClass.prototype = new inheritance(); subClass.baseConstructor = baseClass; if (baseClass.base) { baseClass.prototype.base = baseClass.base; } subClass.base = baseClass.prototype; } Customer = function (firstName, lastName) { Customer.baseConstructor.call(this, firstName, lastName); this.balance = 0; } Customer.prototype.getFullName = function() { Customer.base.getFullName.call(this); } extend(Customer, Person); remove compile-time constructor execution base constructor pointer base method pointers
  • 120.
    More on themany ways to Inherit http://truecode.blogspot.com/2006/08/object-oriented-super-class-method.html Douglas Crockford – my hero http://www.crockford.com/javascript/inheritance.html
  • 121.
    Classical Interfaces -Mixins No compilation in JavaScript so interfaces are tough Need to rely on mutability of JavaScript objects or “mixins” var customer1 = new Customer(); var customer2 = new Customer(); customer1.pay = function(amout) { this.balance -= amount; } customer1.pay(); customer2.pay(); // ERROR!
  • 122.
    Classical Interfaces -Mixins Mutate classes at runtime Think of the implications for AOP var customer1 = new Customer(); var customer2 = new Customer(); Customer.prototype.pay = function(amount) { this.balance -= amount; } customer1.pay(); customer2.pay(); var f = Customer.oldFunction Customer.oldFunction = function() { f.call(this); somethingElse(); }
  • 123.
  • 124.
  • 125.
    XMLHttpRequest The coreof Ajax var xhr = null; try { xhr = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;); } catch(e) { xhr = new XMLHttpRequest(); } xhr.open(&quot;GET&quot;, &quot;http://www.example.com/myResource&quot;, false); xhr.send(null); showResult(xhr); Async = false IE 6 and 7 Everybody Else
  • 126.
    XHR Factory UseFactory pattern to create XHR objects in a cross-browser manner xhrFactory = { create: function() { try { xhr = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;); } cstch(e) { xhr = new XMLHttpRequest(); } return xhr; } } var xhr = xhrFactory.create();
  • 127.
    Synchronous Requests Simplestcase However, JavaScript thread is locked! var xhr = xhrFactory.create(); xhr.open(&quot;GET&quot;, “http://www.example.com/resource”, false); var response = xhr.send(null); Async = false
  • 128.
    Asynchronous Requests Useasync requests to prevent locking the JavaScript thread xhr.open(&quot;GET&quot;, “http://www.example.com/resource”, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { // deal with the response } } } Async = true Regular HTTP status code
  • 129.
    Request Types GETPOST xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); xhr.open(“POST”, “http://www.example.com/resource”, false); var response = xhr.send(“firstName=john&lastName=doe”);
  • 130.
    Data Types POSTdata to the server as either XML or form encoded data Use XHR setRequestHeader() method xhr.setRequestHeader(&quot;Content-Type&quot;,&quot;text/xml&quot;); xhr.setRequestHeader(&quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;); XML Form data
  • 131.
    Response Data Wecan expect the response from the server as XML, JSON, HTML or text xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); alert(response.responseXml); // Should show a [Document] for XML response alert(response.responseText); // Should show the XML, JSON, or HTML data Make sure you set the response type on the server too!
  • 132.
    What Type ofResponse? XML Good for Web Services and XML RPC A bit more work on the client.. browser differences JSON Easy, fast HTML No rendering logic on client bandwidth considerations Just yse what you prefer…..
  • 133.
    XML Response Variousways of dealing with XML data XML DOM – most compatible XPath – fast and easy XSLT – not supported everywhere xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = “”; var customers = response.responseXml.getElementsByTagName(“customer”); for (var i=0; i<customers.length; i++) { var customer = customers[i]; html += “<div>”+customer.childNodes[0].nodeValue+”</div>”; html += “<div>”+customer.childNodes[1].nodeValue+”</div>”; } alert(html);
  • 134.
    JSON Response Needto instantiate the data into JavaScript objects xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = “”; var customers = eval(“(“+response.responseText+”)”); // OR eval(“a = “ + response.responseText); for (var i=0; i<customers.length; i++) { var customer = customers[i]; html += “<div>”+customer.firstName+”</div>”; html += “<div>”+customer.lastName+”</div>”; } alert(html);
  • 135.
    HTML Response Takethe HTML from the server and put it into the web page DOM xhr.open(“GET”, “http://www.example.com/resource”, false); var response = xhr.send(null); var html = response.responseText alert(html);
  • 136.
    Cross-Domain XHR Create<script> element dynamically Response from server includes JavaScript and calls a callback function Called JSONP or XMLP var customers = [{firstName:”John”,lastName:”Doe”}] myCallback(customers); var script = document.createElement(“script”); script.src = “http://www.example.com/resource?callback=myCallback”; document.getElementsByTagName(“head”)[0].appendChild(script); Dynamically generated function call
  • 137.
    Cross-Domain JSONP SecurityThere are serious security risks with JSON or XMLP Also serious risks with JSON in general Return JSON data in comments to prevent non XHR access <!-- [{firstName:”John”,lastName:”Doe”}] -->
  • 138.
  • 139.
    DOM Events NativeEvent object contains information about the event Two approaches to defining events: Inline Unobtrusive Unobtrusive approach requires cross-browser event attachment
  • 140.
    Native Events Documentload, unload, resize, scroll Mouse mouseover, mouseout, mouseup, mousedown, click Key keydown, keyup, keypress Forms focus, blur, change, keydown, keyup, keypress
  • 141.
    onload Event Needthe page JavaScript to execute as soon as possible onload waits for all images etc to load if (document.addEventListener) document.addEventListener('DOMContentLoaded', init, false); <!--[if IE]><script defer src=&quot;ie_onload.js&quot;></script><![endif]--> window.onload = init; Firefox Internet Explorer The rest
  • 142.
    Inline Events Mostsimple event attachment What about separating our control from our view? <div onmouseover=“swapColor(event)” onmouseout=“swapColor(event)”></div>
  • 143.
    DOM Event DecorationAttach event handlers to DOM nodes through JavaScript This can create memory leaks when using anonymous functions var domNode = document.getElementById(“myNode”); domNode.onmouseover = highlight; var domNode = document.getElementById(“myNode”); domNode.onmouseover = function() { domNode.style.color = ‘red’;}; Function pointer Most common way of creating memory leaks in IE
  • 144.
    DOM Event Decorationvar domNode = document.getElementById(“myNode”); domNode.attachEvent(“onmouseover”, highlight); W3C - Firefox var domNode = document.getElementById(“myNode”); domNode.addEventListener(“mouseover”, hightlight, false); Internet Explorer Capture Function pointer Prefixed with “on”
  • 145.
    Event Object InternetExplorer W3C document.documentElement.clientHeight clientX / Y clientX / Y, pageX / Y clientX / Y returns the event coordinates without the document scroll position taken into account, whereas pageX / Y does take scrolling into account. N/A currentTarget The HTML element to which the event handler was attached. keyCode, altKey, ctrlKey, shiftKey keyCode, altKey, ctrlKey, shiftKey Various key event modifiers to check if ctrlKey, shiftKey ctrlKey, shiftKey the Shift or Ctrl key are pressed. srcElement target The HTML element on which the event actually took place. Both properties are supported in Opera and Safari. type type The event type without the “on” prefix. fromElement / toElement relatedTarget from is used only for mouseover and mouseout events. Both properties are supported in Opera and Safari
  • 146.
    Event Questions Howdo you access the Event object? What does “this” refer to in the event handler function?
  • 147.
    Event Object Passedas argument to event handler in W3C model and as a global in IE function swapColor(evt) { } W3C function swapColor() { var evt = window.event; } Internet Explorer
  • 148.
    Handler Execution Scope“ this” is the element that handled the event (W3C) or the window (IE) function swapColor(evt) { this.style.color = “#FF0000”; } W3C function swapColor() { window.event.srcElement.style.color } Internet Explorer
  • 149.
    Cross-Browser Event FaçadeMake Internet Explorer look like W3C eventManager = {}; // Singleton object eventManager.attachEvent = function(elem, type, handler, capture) { // Browser checking for IE vs W3C compliant browser if (elem.attachEvent) { // Create two expando properties with function references elem[‘evt_' + type] = function() { handler.call(elem); }; // Attach one of our expando function references to the event elem.attachEvent('on'+type, elem[‘evt_' + type]); // Set the capture if it was specified if (capture) elem.setCapture(true); } else if (elem.addEventListener) { elem.addEventListener(type, handler, capture); } } IE W3C Sets scope of “this” Event type “mouseover”, etc Detects IE
  • 150.
    Event Flow Eventshave two phases Events are first captured and propagate from the <body> to the target element Event then bubbles back up from the target element to the <body> Capture is very different in IE and W3C but important nonetheless
  • 151.
    Event Flow <body><div> </div> <a onclick=“handler()”></a> </body> Bubble Capture
  • 152.
    Event Creation Programmaticevent creation if (window.attachEvent) // Internet Explorer { element.fireEvent('on'+evtName); } else { // create and init a new event var newEvent = document.createEvent(evtType); newEvent.initKeyEvent(evtName, true, true, document.defaultView, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode); // dispatch new event element.dispatchEvent(newEvent); }
  • 153.
    Exercise 3 –OO JavaScript (if time) Create the following objects: Person class age name height Customer class account balance inherits from Person Put at least 1 prototype method on each class. Create a few customers Get optional application template at: http://www.nitobi.com/gwt/ex3.zip
  • 154.
    Exercise 3 –Possible Solution Person = function(fname, lname, age) { this.firstName = fname; this.lastName = lname; this.age = age; } Person.prototype.getFullName = function() { return this.firstName + &quot; &quot; + this.lastName; } Customer = function(fname, lname, age, balance) { this.balance = balance; Person.call(this,fname, lname, age); } Customer.prototype = new Person(); Customer.prototype.getBalance = function() { return '$' + this.balance;} setupCustomers = function() { var cust1 = new Customer(&quot;John&quot;, &quot;Smith&quot;, 24, 233.23); console.log(cust1.getFullName()); console.log(cust1.getBalance()); }
  • 155.