AJAX and other Advanced JavaScript Techniques
Unix Users Group of New York
Dan Phiffer, July 20, 2006
http://phiffer.org/presentations/ajax/
Hello
I am here to give a talk about AJAX
Or, as I prefer to call it...
"Fancy JavaScript" Fancy JavaScript! Image source
Admittedly "AJAX" is the more widely used term
Coined by Jesse James Garret of Adaptive Path
Stands for Asynchronous JavaScript And XML
Could be simply called Asynchronous JavaScript
Since AJAX doesn't really require using XML
Even the asynchronous part is optional
Thus, "fancy JavaScript"
We live in an era of TechCrunch and Digg and Reddit
Web 2.0 has its share of hype
"AJAX" has a distasteful tinge of marketing-speak
But wait, AJAX is useful!
Lets think of the web as a platform
Lets think of the web as a Unix-like platform
"Mashups" are like piping Unix commands together
AJAX lets you pipe data from one place to another
HTTP handles STDIN and STDOUT
AJAX lets JavaScript speak HTTP
Ansynchronosity is optional, but important
Asynchronous means interacting "a little at a time"
Classic web application model (synchronous) Classic web application model (synchronous) Diagram stolen from Adaptive Path
AJAX web application model (asynchronous) AJAX web application model (asynchronous) Diagram stolen from Adaptive Path
Trade-off is code complexity for UI responsiveness
AJAX apps are harder to build
Sometimes it's worth the extra effort
Use AJAX when the desired user experience dictates it
Some examples of AJAX in the wild:
Some of my own projects:
Time for a break-neck JavaScript primer
Knowledge through syntax osmosis
var message = 'hello world';
var message = "hello world";
var boolean = true;
var integer = 47;
var float = 1.5;
var random = Math.floor(Math.random() * 100);
var array = ['fish', 'rat'];
var object = {fish: 'Joanne', rat: 'Henry'};
function foo() {
    alert('hello, world!');
}
foo();
function foo(msg) {
    alert(msg);
}
foo('¡hola, mundo!');
if (conditional_expression) {
    // Do some stuff
}
if (conditional) {
    // Do some stuff
} else if (some_other_conditional) {
    // Do some other stuff
} else {
    // Otherwise...
}
for (var i = 0; i < 10; i++) {
    // Do this ten times
}
/* A more complex object */
var unigroup = {
    'July 2006': {
        speaker: 'Dan Phiffer',
        topic: 'Fancy JavaScript'
    },
    'August 2006': {
        speaker: 'Somebody else',
        topic: 'Some other topic'
    }
};
/* A more complex object */
var unigroup = {
    'July 2006': {
        speaker: 'Dan Phiffer',
        topic: 'Fancy JavaScript'
    },
    'August 2006': {
        speaker: 'Somebody else',
        topic: 'Some other topic'
    }
};
for (month in unigroup) {
    alert('Join us in ' + month +
          ' for ' + unigroup[month].topic);
}
// The dot and bracket operators are equivalent
var meeting = unigroup['July 2006'];
var speaker = meeting.speaker;
var topic = unigroup['topic'];
Everything is an object (kind of)
Sometimes objects take the form of functions.
function dude(name) {
    this.name = name;
}
// This adds a method to the dude class
dude.prototype.toString = function() {
    if (this.motto) {
        return this.name + ': ' + this.motto;
    } else {
        return this.name + ': Party on, dudes.';
    }
};
var bill = new dude('Bill');
bill.motto = 'Be excellent to each other.';

var ted = new dude('Ted');
alert(bill + ' ' + ted);
JavaScript as a language is pretty simple
The Document Object Model makes it awesome
The DOM is a programmatic interface for markup
Works the same across different markup
(e.g., XML vs HTML)
Works the same across different languages
(e.g., JavaScript vs PHP)
// Diving in
var s = document.getElementById('this_slide');
s.style.background = '#DEDEDE';
s.style.left = s.offsetLeft - 100 + 'px';
s.innerHTML = '<em>Self destructing slide</em>';
<div class="slide" id="another_slide">
    <code><pre> ... </pre></code>
</div>

var s = document.getElementById('another_slide'); var p = s.getElementsByTagName('pre')[0]; s.setAttribute('id', 'something_else'); p.style.border = '1px solid #CCC'; alert(c.parentNode.getAttribute('id'));
XMLHttpRequest is what makes AJAX work
// Requesting HTML markup
var request = new XMLHttpRequest();
request.open('GET', 'index.html', false);
request.send(null);
alert(request.responseText.substr(0, 255));
// Maybe some CSS too?
var request = new XMLHttpRequest();
request.open('GET', 'presentation.css', false);
request.send(null);
alert(request.responseText.substr(0, 255));
// Now we're getting somewhere
var request = new XMLHttpRequest();
request.open('GET', 'eval-me.js', false);
request.send(null);
alert(request.responseText);
// This will execute dynamic JavaScript
eval(request.responseText);
// You can use the DOM with XML files
var request = new XMLHttpRequest();
request.open('GET', 'parse-me.xml', false);
request.send(null);
var xml = request.responseXML;
var child = xml.getElementsByTagName('child')[1];
alert(child.getAttribute('attr'));
// POSTing data
var request = new XMLHttpRequest();
request.open('POST', 'echo.php', false);

// Needed for POST requests
var content_type = 'application/x-www-form-urlencoded';
request.setRequestHeader('Content-Type', content_type);

// Data is sent as URL-encoded key=val
request.send('msg=Hello%20world');
alert(request.responseText);
// Need to proxy off-domain requests
var request = new XMLHttpRequest();
var url = 'proxy.php?url=http://www.unigroup.org/';
request.open('GET', url, false);
request.send(null);
alert(request.responseText.substr(0, 255));
// Asynchronous requests (slightly more complex)
var request = new XMLHttpRequest();
var off_site = 'http://del.icio.us/rss/popular/ajax';
var url = 'proxy.php?url=' + off_site;
request.open('GET', url, true);
request.onreadystatechange = function() {
    if (request.readyState == 4) {
        var xml = request.responseXML;
        var first = xml.getElementsByTagName('item')[0];
        var title = first.getElementsByTagName('title')[0];
        alert(title.firstChild.nodeValue);
    }
}
request.send(null);
// One last caveat -- Microsoft handles things differently
if (window.XMLHttpRequest) {
    var request = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    var request = new ActiveXObject("Microsoft.XMLHTTP");
}
Do we need all this fancy JavaScript?
No we don't
Even so, AJAX is handy in some cases
When it makes sense to use AJAX
(according to PPK)
When more responsiveness enhances the user experience
IFRAMEs and hidden FORM elements can do the same thing
// AJAX, without XMLHttpRequest
function callback(js) {
    eval(js);
}
document.frames[0].src = 'async.php';

<!-- async.php --> <script type="text/javascript"> var js = 'alert("Hello, world");'; parent.callback(js); </script>
XMLHttpRequest offers greater flexibility and convenience
Unfortunately JavaScript runs pretty slow
element.innerHTML instead of the DOM for building pages ref
Create new threads with setTimeout(..., 0) when necessary
Test for slow code using Date.getTime() ref
Circular references cause browsers to leak memory ref
Internet Explorer is the worst offender
High-level live search walkthrough: See: BitFlux LiveSearch (js)
Inline text editing walkthrough: See: included example (js)
RSS parsing walkthrough: See: included example (js)
Programming is mostly about debugging
Yay for Firefox Firefox has the best tools for debugging JavaScript
The JavaScript console is your friend
JavaScript Console Your console may have a bunch of crap in it.
The Venkman JavaScript debugger Venkman debugger
In theory Internet Explorer has a debugger
It's usually better to just log messages to the page
Some assorted debugging resources
3 popular JavaScript frameworks
I like to write my own libraries
Some final considerations...
JavaScript can do some strange and wonderful things
Consider whether your users need JavaScript
XMLHttpRequest is not a web standard (yet)
Leave ample time for browser testing
AJAX apps can suffer from the plight of Flash sites
No addressible URLs → poor search rankings
Fail gracefully
This will let you play around a bit
A few resources you might want to check out:
(no more slides)