GitHub: daffl.github.com
Twitter: @daffl
- Prototype - Part of the AJAX support for Ruby on Rails
- Mootools - Lighweight OO framework for JavaScript
- YUI - JavaScript and CSS framework wit UI controls and build tools
- Dojo Toolkit - Toolkit for rapid JavaScript application development, packaging and widget system (Dijit)
- ExtJS - UI heavy framework for rich internet applications
- jQuery - Library to simplify DOM interaction, effects and AJAX interaction
- Originally an add-on library extension of YUI
- Optional interoperability with Prototype and jQuery
- Big selection of pre packaged UI controls
- Grids, Charts, Tabs, Trees
- Window manager
- Form elements, combobox
- GPL for open source projects (commercial otherwise)
- MVC parts in version 4.0
- ~ 500Kb
- Web Desktop demo
- Simplifies DOM manipulation and traversal and event handling
- AJAX support
- Effects
- UI elements with jQuery UI (~200Kb)
- Eliminates cross browser differences
- Plugin mechanism
- Fully open source (MIT licensed)
- ~ 32Kb
jQuery
!javascript
$(document).ready(function() {
$('button').click(function() {
var name = $('[name="your-name"]').val();
$('#mydiv').html('Hi ' + name);
});
});
Markup
!html
<input type="text" name="your-name" />
<button>Say Hi</button>
<div id="mydiv"></div>
JavaScript only knows function scope
!javascript
for(var i = 0; i < 10; i++) {
var x = 'testing';
(function(arg) {
var y = 42;
})(i);
}
Global variables
!javascript
function test() {
var local = 42;
global = 'global';
}
test();
!javascript
var App = {
init : function() {
/* ... */
},
Dummy : {
sayHi : function(name) {
return 'Hi ' + name;
}
}
}
App.Blog = {
getPosts : function() { /* ... */ }
}
console.log(App.Dummy.sayHi('David'));
!javascript
var APP = (function() {
// Do stuff
var privateVariable = 'Hello ',
sayHi = function(name) {
return privateVariable + name;
};
// Return API
return {
init : function() { /* ... */ },
hi : sayHi
}
})();
console.log(APP.sayHi('David'));
!javascript
(function($) {
$.fn.myPlugin = function(name) {
var self = $(this),
span = $('<span>'),
button = $('<button>Say Hi</button>');
button.click(function() {
self.find('span').html('Hi ' + name);
});
self.append(span).append(button);
return this;
}
})(jQuery);
// <div id="mydiv"></div>
$('#mydiv').myPlugin('David');
AMD: CommonJS specification for asynchronously loading dependencies.
!javascript
// say_hi.js
define(function() {
var privateVariable = 'Hello ';
return {
sayHi : function(name) {
return privateVariable + name;
}
}
});
// module.js
define(['say_hi.js'], function(hisayer) {
return {
result : hisayer.sayHi('David'),
sayHi : hisayer
}
});
// app.js
var module = require('module.js', function(module) {
module.sayHi('You'); // Hello You
module.result; // -> Hello David
});
Development:
- Functionality split into files
- Unmodified source code available for debugging
Production:
- Minimize HTTP requests
- Leverage caching
- Minimize file size
- JSMin - JavaScript minifier by Douglas Crockford
- YUI compressor - CSS and JavaScript minifier
- Google Closure compiler - JavaScript minifier
- StealJS - JavaScript and dynamic asset loader and build environment
- RequireJS - JavaScript file and module loader (AMD)
JSON: A text based data exchange format
- Subset of JavaScript
- Supported types
- Primitives (String, Number, Boolean, null)
- Arrays
- Objects
Example
!javascript
{
"username" : "User 1",
"emails" : ["user@example.com", "other@mail.com"]
"address" : {
"street" : "Example street",
"city" : "Calgary"
},
"age" : 42
}
AJAX: Issue HTTP requests outside of the normal browser request/response cycle using JavaScript.
!javascript
$('#content').load('ajax/test.html', function() {
alert('Content loaded.');
});
Loading JSON
!javascript
$.ajax({
url: 'http://example.com/user.json',
dataType: 'json',
success: function(data) {
alert(data.username);
}
});
REST: A resource oriented software architecture style for distributed systems
URI: A unique identifier for a resource (e.g. http://example.com/user/1, tel:911)
- Client-Server
- Stateless
- Caching
- Well defined operations
- Layered architecture
In HTTP:
- GET - Request a representation of a resource
- POST - Update a resource
- PUT - Create a new resource
- DELETE - Delete a resource
- HEAD - Like GET but without payload
Request
GET /users/2 HTTP/1.1
Host: example.com
Accept: application/json
Accept-Charset: utf-8,ISO-8859-1
Response
HTTP/1.1 200 OK
Date: Fri, 26 Feb 2010 13:14:07 GMT
Server: Awesome NodeJS server
Content-Type: application/json; charset=utf-8
Content-Length: 55
{
"username" : "UserX",
"password" : "supersecret"
}
Request
POST /users HTTP/1.1
Host: example.com
Content-Type: text/xml
Content-Length: 77
Accept: application/xml,application/json
Accept-Charset: ISO-8859-1,utf-8
<user>
<username>UserX</username>
<password>supersecret</password>
</user>
Response
HTTP/1.1 201 Created
Date: Fri, 26 Feb 2010 11:39:07 GMT
Server: Awesome NodeJS server
Content-Location: http://example.com/users/2
A client side MVC style framework to structure JavaScript applications.
!javascript
var Photo = Backbone.Model.extend({
// Default attributes for the photo
defaults: {
// Ensure that each photo created has an `src`.
src: "placeholder.jpg",
caption: "A default image",
viewed: false
},
initialize: function() {
}
});
!javascript
var PhotoGallery = Backbone.Collection.extend({
// Reference to this collection's model.
model: Photo,
// Filter down the list of all photos that have been viewed
viewed: function() {
return this.filter(function(photo){ return photo.get('viewed'); });
},
// Filter down the list to only photos that have not yet been viewed
unviewed: function() {
return this.without.apply(this, this.viewed());
}
});
Client side MVC framework for building rich web applications. Supports jQuery, Zepto, Mootools, Dojo, YUI.
- can.Construct - inheritable constructor functions
- can.Observe - observable objects
- can.Model - observes connected to a RESTful JSON interface
- can.view - template loading, caching, rendering
- can.EJS - live binding templates
- can.Control - declarative event bindings
- can.route - back button and bookmarking support
A view
!html
<script type="text/ejs" id="todos">
<ul>
<% for( var i = 0; i < this.length; i++ ) { %>
<li><%= this[ i ].name %></li>
<% } %>
</ul>
</script>
Controls and Models
!javascript
var Todo = can.Model({
findAll : 'GET /todos',
findOne : 'GET /todos/{id}',
create : 'POST /todos',
update : 'PUT /todos/{id}',
destroy : 'DELETE /todos/{id}'
}, {});
var Control = can.Control({
'button click' : function() {
document.findElementById('mydiv').innerHtml =
can.view('todos', Todo.findAll());
}
});
Phonegap: A cross platform (iOS, Android, Blackberry, WebOS, Symbian) framework to run single page applications providing access to mobile phone functionality.
!javascript
navigator.camera.getPicture(function(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
}, null, {
quality: 50,
destinationType: Camera.DestinationType.DATA_URL
});
Mobile development frameworks
Client side testing is still not a common practise
Unit tests
Test if separate contained parts (e.g. a module) return expected values, injecting mock dependencies if necessary.
Functional tests
Test if user interaction works as expected
A behaviour driven development (BDD) framework to test JavaScript code:
!javascript
function sayHi(name) {
return 'Hi ' + name;
}
function getAnswer() {
return 42;
}
describe('A test suite', function () {
it('Should say hi to David', function() {
expect(sayHi('David')).toBe('Hi David');
});
it('Should return the answer to all questions, function() {
expecte(getAnswer()).toBe(42);
}
});
Originally part of jQuery but evolved into a separate unit testing suite:
!javascript
module('Hi Sayer');
test('Saying hi', function() {
var actual = sayHi('David');
equals(actual, 'Hi David', 'Said Hi');
});
test('Returns the answer to all questions', function() {
equals(answer(), 42, 'Got the answer to all questions');
});
A functional testing suite to simulate user input based on QUnit and jQuery:
!javascript
module("jQuery Demo tester",{
setup: function() {
S.open('demo.html')
}
});
test("Plugin says hi",function(){
// Type some text into <input name="your-name" />
S('input[name="your-name"]').click().type("David")
// Click the button
S('button').click();
// Check the HTML content
S('#mydiv').html('Hi David');
});
!javascript
/**
* A Person class.
* @param name The name of the person
*/
var Person = function(name) {
this.name = name;
}
/**
* Says hi.
* @return {String} A string saying hi
*/
Person.prototype.sayHi = function() {
return 'Hi ' + this.name;
}
Documentation generator for JSDoc style comments:
!javascript
/*
* @page index CRM
* @tag home
*
* ## Little CRM
*
* Our little CRM only has two classes:
*
* * Customer
* * Order
*/
/**
* @parent index
* A function that says hi
* @param {String} name The name to say hi to
* @return {String} The saying hi string
*/
function sayHi(name) {
return 'Hi ' + name;
}
A quick-and-dirty, hundred-line-long, literate-programming-style documentation generator.
Originally for Coffeescript but works with JavaScript as well.
!javascript
// # Saying hi
// This is my litte program that says hi.
// A function that says hi
// name - The name to say hi to
function sayHi(name) {
return 'Hi ' + name;
}