如下是對XMLHttpRequest的封裝,爲一個簡易的工廠模式
/* AjaxHandler interface. */
var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXhrObject']);
/* SimpleHandler class. */
var SimpleHandler = function() {}; // implements AjaxHandler
SimpleHandler.prototype = {
request: function(method, url, callback, postVars) {
var xhr = this.createXhrObject();
xhr.onreadystatechange = function() {
if(xhr.readyState !== 4) return;
(xhr.status === 200) ?
callback.success(xhr.responseText, xhr.responseXML) :
callback.failure(xhr.status);
};
xhr.open(method, url, true);
if(method !== 'POST') postVars = null;
xhr.send(postVars);
},
createXhrObject: function() { // Factory method.
var methods = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
for(var i = 0, len = methods.length; i < len; i++) {
try {
methods[i]();
}
catch(e) {
continue;
}
// If we reach this point, method[i] worked.
this.createXhrObject = methods[i]; // Memoize the method.
return methods[i];
}
// If we reach this point, none of the methods worked.
throw new Error('SimpleHandler: Could not create an XHR object.');
}
};
/* Usage. */
var myHandler = new SimpleHandler();
var callback = {
success: function(responseText) { alert('Success: ' + responseText); },
failure: function(statusCode) { alert('Failure: ' + statusCode); }
};
myHandler.request('GET', 'script.php', callback);
如下是輔助類的實現:
// Constructor.
var Interface = function(name, methods) {
if(arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length
+ "arguments, but expected exactly 2.");
}
this.name = name;
this.methods = [];
for(var i = 0, len = methods.length; i < len; i++) {
if(typeof methods[i] !== 'string') {
throw new Error("Interface constructor expects method names to be "
+ "passed in as a string.");
}
this.methods.push(methods[i]);
}
};
// Static class method.
Interface.ensureImplements = function(object) {
if(arguments.length < 2) {
throw new Error("Function Interface.ensureImplements called with " +
arguments.length + "arguments, but expected at least 2.");
}
for(var i = 1, len = arguments.length; i < len; i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error("Function Interface.ensureImplements expects arguments "
+ "two and above to be instances of Interface.");
}
for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j];
if(!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: object "
+ "does not implement the " + interface.name
+ " interface. Method " + method + " was not found.");
}
}
}
};
/* AjaxHandler interface. */
var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXhrObject']);
/* SimpleHandler class. */
var SimpleHandler = function() {}; // implements AjaxHandler
SimpleHandler.prototype = {
request: function(method, url, callback, postVars) {
var xhr = this.createXhrObject();
xhr.onreadystatechange = function() {
if(xhr.readyState !== 4) return;
(xhr.status === 200) ?
callback.success(xhr.responseText, xhr.responseXML) :
callback.failure(xhr.status);
};
xhr.open(method, url, true);
if(method !== 'POST') postVars = null;
xhr.send(postVars);
},
createXhrObject: function() { // Factory method.
var methods = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
for(var i = 0, len = methods.length; i < len; i++) {
try {
methods[i]();
}
catch(e) {
continue;
}
// If we reach this point, method[i] worked.
this.createXhrObject = methods[i]; // Memoize the method.
return methods[i];
}
// If we reach this point, none of the methods worked.
throw new Error('SimpleHandler: Could not create an XHR object.');
}
};
/* Usage. */
var myHandler = new SimpleHandler();
var callback = {
success: function(responseText) { alert('Success: ' + responseText); },
failure: function(statusCode) { alert('Failure: ' + statusCode); }
};
myHandler.request('GET', 'script.php', callback);