Treating Ajax as an “all or nothing” technology.
It will take a lot of time and effort to create a “separate but equal” non-Ajax version.
Progressive Enhancement
Gotta keep 'em separated
<p style="font-weight: bold">This is an introductory paragraph.</p>
<p class="introduction">This is an introductory paragraph.</p>
p.introduction { font-weight: bold; }
<a href="javascript:window.open('help.html')">contextual help</a>
<a href="#" onclick="window.open('help.html'); return false;">contextual help</a>
<a href="help.html"
onclick="window.open(this.getAttribute('href')); return false;">contextual help</a>
<a href="help.html" class="help">contextual help</a>
function doPopups() {
if (document.getElementsByTagName) {
var links = document.getElementsByTagName("a");
for (var i=0; i < links.length; i++) {
if (links[i].className.match("help")) {
links[i].onclick = function() {
window.open(this.getAttribute("href"));
return false;
};
}
}
}
}
Avoid:
<a href="#">
<a href="javascript:">
A quick introduction...
function getHTTPObject() {
var ajax = false;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
return ajax;
}
request = getHTTPObject();
request.onreadystatechange = doSomething;
request.open( "GET", "myfile.php", true );
request.send(null);
function doSomething() {
if (request.readyState == 4) {
// code goes here
}
}
function doSomething() {
if (request.readyState == 4) {
if (request.status == 200) {
// it worked
} else {
// something went wrong
}
}
}
responseXML
getElementsByTagName
,appendChild
, etc.text/xml
responseText
“But it's a whole different paradigm — the old rules don't apply.”
“But it's not a website anymore — it's more like a desktop application.”
XMLHttpRequest
instead of the server.Back-end architecture should be modular.
Web pages are created by joining modules together (e.g. navigation, log-in form, shopping cart, etc.)
[Hint: APIs are very modular]
A page that includes a form: when the form is submitted, the same page is returned with just part of the page updated.
Example: Contact form (JS)
function prepareForm(formId) {
if (!document.getElementById) return false;
if (!document.getElementById(formId)) return false;
document.getElementById(formId).onsubmit = function() {
var data = "";
for (var i=0; i<this.elements.length; i++) {
data+= this.elements[i].name;
data+= "=";
data+= escape(this.elements[i].value);
data+= "&";
}
return (!sendData(data,"formlogic.php"));
};
}
function sendData(data,file) {
var request = getHTTPObject();
if (request) {
request.onreadystatechange = function() {
doSomething(request);
};
request.open( "POST", file, true );
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.send(data);
return true;
} else {
return false;
}
}
Clicking on a link returns the same page but with one portion changed (different data or different view of data).
Example: Shopping cart (JS)
function prepareLinks(containerId) {
if (!document.getElementById) return false;
if (!document.getElementById(containerId)) return false;
var links = document.getElementById(containerId).getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
links[i].onclick = function() {
var data = this.getAttribute("href").split("?")[1];
return (!sendData(data,"shoppingcart.php"));
};
}
}
eval()
innerHTML
So simple, it's a microformat: AHAH
Use the XMLHttpRequest object like a dumb waiter:
Client-side processing is kept to a minimum: all the heavy lifting happens on the server.
Example: Sorting tables (JS)