5. Let’s Face It!
• You can hardly be another…
• Better to start from niche:
3
6. The Trend
• No harm
– Win-win business model between customers, the
startup, and partners
• Make a (small) group of people happy
– Very happy
• Service available everywhere
– Run on either desktops, smart phones, tablets, etc.
– Blurred line between web sites and apps
4
7. We, as Developers, are Not Happy
• Being able to run a service on either desktops,
smart phones, or tablets means:
– Constantly learning new SKDs
– Coding again and again for the same function
– Killing bugs that fly across platforms
– Tedious (and endless) compatibility testing
– And more…
5
9. Trick 1: Leveraging the Cloud
• Implement your core services in the cloud
• Expose them through HTTP
– E.g., define RESTful API
• Pros:
– Simplifies development of common modules
– Easy data migration
– Low start-up cost
7
13. About the Next Two Lectures
• Javascript
– This week: the basics
– Next week: advanced topics on modular design
11
14. Disclaimers
• Does not mean you should avoid native codes
completely
– Mixing native code with HTML+CSS+Javascript
simplifies jobs sometimes
• This is not a comprehensive overview
– We go deep if necessary
– Covers only a tiny portion of the modular design
12
17. Javascript
• Official name is ECMAScript
– v1.5 in 2000
• Supported by major browsers
– Firefox 4 and IE 9 will support v1.8.5
• Looks like Java in:
– Statement syntax and naming conventions
• But has nothing to do with Java in the rest
– Execution
– Scopes
– Type system
– Object/function manipulation
– Inheritance
15
18. A Scenario 1. Open a browser
2. Tell it an URL (either
directly by typing or
indirectly by clicking a
portal/bookmark)
3. Your browser sends an
1. HTTP Request: GET
HTTP request to a web
Client
(Browser) URL: http://en.wikipedia.org/wiki/Apache_Maven
Server
(Web App)
site and gets an HTTP
response containing a
Internet web page written in
2. HTTP Response: 200 OK XHTML+CSS+Javascript
XHTML:
<!DOCTYPE html PUBLIC ... >
<html xmlns=“http://www.w3.org/1999/xhtml”>
4. The browser then parses
<head>...</head>
<body>
XHTML+CSS and renders
<div id=“content”> the page
<h1 id=“firstHeading”>Apache Maven</h1>
<div id=“bodyContent”>
<p>Maven is a software tool...</p>
5. When you click or submit,
</div>
</div>
the browser either repeats
</body> Step 2 or tells Javascript to
</html>
update the page.
16
19. Web Development
• HTML
– Defines DOM elements in a document
– Tutorial
• CSS
– Specifies the presentation of each DOM element
– Tutorial
• Javascript
– Modifies the DOM elements in react to user
behavior (e.g., clicks)
17
20. • XHTML: Hello World! (1/2)
1. <html>
2. ... <!-- header tells where CSS and Javascript files are -->
3. <body>
4. <h1>
5. Welcome to <span id="logo">world</span>!
6. </h1>
7. </body>
8. </html> • CSS:
1. .logo-over {
• Javscript: 2.
3. }
background-color: #DDE5FF;
1. window.onload = function() {
2. initLogo();
3. // init other elements here
4. };
5. var initLogo = function() {
6. var logoEl = document.getElementById('logo');
7. logoEl.onmouseover = function() {
8. addClass(logoEl, 'logo-over');
9. };
10. logoEl.onmouseout = function() {
11. removeClass(logoEl, 'logo-over');
12. };
13. }
14. var addClass = function(el, cls) { ... // addClass and removeClass
18
21. Hello World! (2/2)
• A few observations:
– There is a global scope
– There are offered objects (e.g., window, document)
• window is the default object
– Variables have no type (e.g., var initLogo)
– Functions are objects
– The offered browser/DOM objects have “event
handler” properties (e.g., window.onload)
• Event handlers are function objects
19
22. Executing Javascript
1. <html>
2. ... (1/2)
3. <body>
4. <h1 id="head" onmouseover=“window.alert('Hello');">
5. ...
6. </h1>
7. </body> 1. window.onload = function() {
8. </html> 2. var headEl = document.getElementById('head');
3. headEl.onmouseover = function() {
4. window.alert('Hello');
5. }
6. }
• Codes inside <script> are executed immediately, even
when HTML is still loading
– Don’t expect the DOM elements to be ready when running in
the global scope
• The bodies of event handlers will not be executed until the
corresponding events are fired
– When programming GUI, you think what to do when events are
fired, not when main() is executed
20
23. Executing Javascript
• To register event (2/2)
handlers: 1. var initLogo = function() {
2. var logoEl = document.getElementById('logo');
3. logoEl.onmouseover = function() {
4. addClass(logoEl, 'logo-over');
5. };
6. logoEl.onmouseout = function() {
7. removeClass(logoEl, 'logo-over');
8. };
9. }
10. ... // addClass and removeClass
why not:
1. var initLogo = function() {
2. var logoEl = document.getElementById('logo');
3. logoEl.onmouseover = addClass(logoEl, 'logo-over');
4. logoEl.onmouseout = removeClass(logoEl, 'logo-over');
5. }
6. ... // addClass and removeClass
– add/removeClass are invoked immediately
– onmouseover/out get the return values
21
24. Scopes
• There are only two types of scope in Javascript:
– window/global scope
• Variables can be used anywhere, e.g., window.onload = ..., onload
= ..., var initLogo = ...
– Function scope
• Variables are only available inside a particular function, e.g.,
function() { var logoEl = ... };
• There is no block scope (below v.1.7)
1. var f = function() {
2. for(var i = 0; i < 10; i++) {
3. ...
4. }
5. var j = i; // j equals 10
6. var i; // i equals 10
7. }
– i exists after the loop
– Variables can be re-declared, and old values preserve
22
25. Types (1/4)
• 5 primitive types:
1. var i = 15;
– undefined, null, 2. alert(typeof i); // number
boolean, number, string 3. var str = 'Hello'; // or "Hello"
4. alert(typeof str); // string
• 2 object types:
– object, function
1. var str = new String('Hello'); 1. // object literal (JSON)
2. alert(typeof str); // object 2. var user1 = {
3. // function literal 3. name: 'John',
4. var add = function(a, b) { 4. friends: ['Bob', 'Paul']
5. return a + b; 5. };
6. }; 6. alert(typeof user1); // object
7. alert(typeof add); // function 7. var User = function(name, friends) {
8. alert(typeof add(1, 2)) // number 8. this.name = name;
9. alert(typeof add('1', 2)) // string 9. this.friends = friends;
10. };
11. alert(typeof User); // function
• Nothing else! 12. // use a function as a constructor
13. var user2 = new User(...);
14. alert(typeof user2); // object
23
26. Types (2/4)
• When declaring a function, you create a function
object
• A function can be used as a constructor to create
objects
– A constructor simply add default members to the
objects, which increases reusability
– String, Date, Array, etc. are constructors rather than
types
• In Java, classes are types
• In Javascript, classes usually refer to constructors
24
27. Types (3/4)
• Objects of the same type can have distinct
members
– This is how constructors work to create different
classes
– Classes are soft; members can be added on-the-fly
1. var user1 = new Object(); 1. var User = function(name) {
2. user1.name = 'John'; 2. this.name = name;
3. user1.toString = function() { 3. this.toString = function() {
4. return this.name; 4. return this.name;
5. }; 5. }
6. var user2 = { 6. };
7. name: 'Paul', 7. var user3 = new User('Bob');
8. toString: function() { 8. alert(user3); // Bob
9. return this.name; 9. // add distinct method to user3
10. } 10. user3.sleep = function() {
11. }; 11. ...
12. alert(user1); // John 12. }
13. alert(user2); // Paul
25
28. Types (4/4)
• Unlike Java, both primitives and objects can
have properties and methods
– The difference is that primitives can only have
members defined in the wrappers’ constructors
1. var str1 = 'Hello Smail!'; // primitive
2. var str2 = new String('Hello Smail!'); // object
3. alert(str1.slice(6, 11)); // Smail
4. alert(str2.slice(6, 11)); // Smail
5. var f = function() { ... };
6. str1.someMethod = f; // add custom method
7. str2.someMethod = f; // add custom method
8. alert(typeof str1.someMethod); // undefined
9. alert(typeof str2.someMethod); // function
26
29. Primitives vs. Objects
• Memory schema?
• Assign/pass/compared by value or reference?
• Similar to Java
– Except strings are primitives
Type Assigned by Passed by Compared by
boolean Value Value Value
number Value Value Value
string Immutable Immutable Value
object/function Reference Reference Reference
27
30. Objects in Your Browser
• Browser objects (provided):
– navigator: contains information about the browser
– window: represents an open window in the browser
– location: contains information about the current URL
• DOM objects (provided):
– document: represents a loaded XHTML document in a window
– XHTML elements: represents the elements of a document
• Custom objects:
– Instances of Array, Boolean, Date, Number, String,
RegExp, etc.
– Instances of XMLHttpRequest: represents (asynchronous)
HTTP request
• See Javascript Object Reference for other objects and their
useful properties/methods
28
31. Functions (1/3)
• Functions are just normal objects except that they are runnable
– Can have members, e.g., Student.MAX_GRADE, etc.
• Memory schema? (Homework)
1. var f = function() { ... }; // function statement
2. var f = (function() { ... })();
– Former parentheses indicate a function expression
• What about functions created inside an executing function?
1. (function() {
2. var el = document.getElementById('...');
3. var i = ...;
4. el.onclick = function() { // closure
5. var j = Math.sqrt(i);
6. ...
7. };
8. ...
• Closure 9. })();
– Has direct access to local variables of the executing parent function
– The local variables needs to be kept inside memory in case the closure
get called
29
32. Functions (2/3)
• Be careful about this:
1. <html> 1. var showContent = function() {
2. ... 2. alert(this.innerHTML);
3. <body> 3. };
4. <h1 id="hd">Hello!</h1> 4. onload = function() {
5. </body> 5. showContent(); // undefined
6. </html> 6. var el = document
7. .getElementById('hd');
8. // Hello! upon click
9. el.onclick = showContent;
10.};
• When a function is executed, this always binds to the
“current owner” of that function
– window, when called directly by name
– the creating object, when called as a constructor
– the object to which ‘.’ is applied, when called as a method
30
33. • To specify the binding: Functions (3/3)
1. var showName = function(postfix) {
2. alert(this.name + (postfix || ''));
3. };
4. var user1 = {name: 'John'};
5. var user2 = {name: 'Bob'};
6. showName('!'); // undefined!
7. user1.showName = showName;
8. user1.showName('!'); // John!
9. showName.call(user1, '!'); // John!
10.showName.call(user2, '!'); // Bob!
11.showName.apply(user1, ['!']); // John!
• There is an implicit arguments object inside each
function
– Works with apply() for easy delegation
– Not an array; doesn't support array methods
1. // can accept other arguments
2. var delegateFunc = function(user, func) {
3. var args = []; // JSON that creates an empty array
4. for(var i = 2; i < arguments.length; i++)
5. args.push(arguments[i]);
6. delegatedFunction.apply(user, args);
7. }; 31
35. Inside Blocks (1/3)
• Read this 20-min tutorial (basic part) first
• String literals can be single- or double-quoted
– No escape is needed when interleaving ‘...’ and “...”
E.g, var htmlFrag = '<div class="col-1">' + i + '</div>';
• Javascript has objects literals named JSON (Javascript
Simple Object Notation)
– Never append “,” to the last member; IE will hang when
executing the line
• Members of an object can be accessed by names
1. // object literal (JSON)
2. var user1 = {
3. name: 'John',
4. friends: ['Bob', 'Paul'] // no comma here!
5. };
6. alert(user1['name']); // John
7. alert(user1['friends'][1]); // Paul
33
36. Inside Blocks (2/3)
• Every object can be used as a map in a loop
1. var user1 = {
2. name: 'John',
3. friends: ['Bob', 'Paul']
4. };
5. for(var member in user1) {
6. alert(user1[member]); // the member value
7. }
• Use === (and !==) instead '' == '0' //false
of == (and !=) '' == 0 //true
'0' == 0 // true
– The latter does not check false == 'false' // false
the type of operands false == 0 // true
false == undefined // false
• Rules are complicated: false == null // false
null == undefined // true
– All the expressions at left ' trn' == 0 // true
return false with ===
34
37. Inside Blocks (3/3)
• It is a good practice to assign/pass/return the
variables of right types
– Document the types in /** ... */
• There are predefined global functions
– E.g., to converting between strings, numbers, and
objects:
• string number: parseInt(), parseFloat()
• object number: Number()
35
38. Eval
• Executing/evaluating codes in a string:
1. var httpResp = '{name:"Paul",age:18}'; // string
2. var respObj = eval('(' + httpResp + ')');
3. alert(respObj.name); // Paul
– eval accepts statements and runs at global scope
• ‘{’ means start of a block
– ‘(’ and ‘)’ makes httpResp an expression
• ‘{‘ is part of JSON
• Eval is slow
– It invokes an interpreter
• Don’t abuse eval:
1. var propName = 'age';
2. var user = ...
3. // how to obtain the specified property of a user object?
4. var age = eval('user.' + propName); // don’t do this
5. var age = user[propName];
36
40. • It's a common task to
Functions in Loops
associate an array of 1. var rowEls = document.getElementsByTag('tr');
DOM elements with 2. for(var i = 0; i < rowEls.length; i++) {
3. var rowEl = rowEls[i];
their respective 4. rowEl.onmouseover = function() { // closure
handlers: 5.
6. }
addClass(rowEl, 'row-over');
• The code is buggy! 7. }
– rowEl is shared by all handlers (closures)
– Memory schema?
• Patch: 1. var rowEls = document.getElementsByTag('tr');
2. for(var i = 0; i < rowEls.length; i++) {
3. var rowEl = rowEls[i];
4. rowEl.onmouseover = (function(el) {
5. return function() { // closure
6. addClass(el, 'row-over');
7. };
8. })(rowEl);
9. }
– The inner closure accesses el rather than rowEl
– el is passed by reference; won’t change as loop proceeds
38
42. • DOM tree:
DOM Elements
– The entire document is a document
node (1/2)
– Every HTML element is an element node
1. <html>
– The text in the HTML elements are text
nodes 2. <head>
• Text separated by elements become distinct 3. <title>My title</title>
text nodes 4. </head>
– Every HTML attribute is an attribute node 5. <body>
– Comments are comment nodes 6. <h1>My header</h1>
7. <a href="...">My link</a>
8. </body>
9. </html>
40
43. • Accessing the DOM: DOM Elements
– el.id/className
• string
• multiple class names are separated by spaces
(2/2)
– el.nodeName
• E.g., “#document”/“H1”/“#text”/“href” for document/element/text/attribute
– el.nodeValue
• E.g., “null”/“null”/“My title”/“http://... ”
– el.nodeType
• E.g., 9/1/3/2
– el.parentNode
– el.first/lastChild
– el.nextSibling
– el.childNodes
– el.attributes
– el.innerHTML
– el.style
– el.getElementById(id)
– el.getElementsByTagName(n)
– el.appendChild(node)
• innerHTML is preferred
– el.remove(node)
• See other members
41
46. Event Handling (1/2)
• Events handlers:
– E.g., window.onload, el.onclick/onmouseover/onmouseout/
onmousedown/onmousemove/onmouseup/onresize/onfocus/
onblur, etc.
• What is the problem here?
1. <html> 1. var show = function() {
2. <body> 2. alert(this.innerHTML);
3. <h1 onclick="show();">...</h1> 3. }
4. </body>
5. </html> – Equivalent to:
1. var h1El = ...;
2. h1El.onclick = function() {
• Fix: 3. show(); // undefined
4. }
1. <html>
2. <body>
3. <h1 onclick="alert(this.innerHTML);">...</h1>
4. </body>
5. </html>
or 1. var h1El = ...;show;
2. h1El.onclick =
44
47. Event Handling
• The event object:
– IE: window.event (2/2)
– Others: passed as 1. el.onclick = function(e) {
2. var e = e || window.event; // for IE
an argument 3. alert(e.clientX);
• Members: 4. }
W3C IE Description
clientX/Y clientX/Y The mouse coordinates (relative to upper-left corner of
the window) at event time
type type A string indicator, e.g., “mouseover”, “click”, etc.
target srcElement The element that the event originated from. Not
necessary the one to which the handler is assigned
relatedTarget from/toElement On “mouseover” (resp. “mouseout”), indicates the
element that the mouse has left from (resp. moved into)
preventDefault() returnValue Cancels any default action associated with the event
stopPropagation() cancelBubble Prevent the event from bubbling
45
48. Canceling Events
• Sometimes, you may want to cancel the default
browser behavior for an event
– E.g., Prevent the <form> from being submitted to
perform validation first and then AJAX request
• How?
1. formEl.onsubmit = function(e) {
2. var e = e || window.event;
3. if(e.preventDefault) e.preventDefault();
4. else e.returnValue = false;
5. ... // validation and AJAX
6. }
1. formEl.onsubmit = function(e) {
2. ... // validation and AJAX
or 3. return false;
4. }
• Difference?
46
49. Event Bubbling (1/2)
1. <body onclick="alert(body clicked);">
2. <h1 onclick="alert(h1 clicked);">
3. <a href="..." onclick="alert(a clicked); return false;">
4. A link
5. </a>
6. </h1>
7. </body>
• When you click <a>, you get 3 popups
– “a clicked” “h1 clicked” “body clicked”
• Events “bubble up” to the document object
– event.target/srcElement refer to the originator
– Use this in handler to access the current element
• Event handlers of an element may be executed multiple
times if the element has children (including text nodes)
– TODO Solve the blink issue of Smail
47
50. Event Bubbling (2/2)
• The event.relatedTarget (or fromElement and
toElement in IE) is commonly used by a
container to detect whether the mouse is still
within itself during a “mouseover” or
“mouseout” event
• Stop bubbling:
1. el.onclick = function(e) {
2. var e = e || window.event;
3. if(e.stopPropagation) e.stopPropagation();
4. else e.cancelBubble = true;
5. ...
6. }
48
52. AJAX (1/3)
• Synchronous vs. asynchronous request:
1. var req = ...; 1. var success = function() {
2. var resp = req.send(); // synchronous 2. ... // do something on success
3. ... // blocked until resp is obtained 3. };
4. var req = ...;
• AJAX (Asynchronous 5. req.send(success); // asynchronous
6. ... // executed immediately
Javascript And XML):
The process retrieving data from the server
asynchronously without leaving the current page
– Despite the name, data are not necessary in XML format
– Actually, JSON is more common due to eval()
• AJAX is not a silver bullet:
– Complicates management of history, bookmarking, etc.
– Increases the number of user-generated requests
– Obstructs the web crawlers
50
54. AJAX (3/3)
• Handling response:
1. ajaxRequest('GET', encodeURI('mails/3347'), {
2. Accept: 'application/json'
3. }, null, function(status, headers, body) { // success callback
4. // body should be a mail in JSON string
5. var mail = eval('(' + body + ')'); // make sure body is an expression
6. ... // process mail object
7. }, function(status, headers, body) { // error callback
8. alert('Error: ' + status);
9. }, null); // run callbacks in global scope
52