Using the XMLHttpRequestObject, I was able to create an asynchronous request to fetch the source of my .js file. Then I create a new script object and set the .text or .innerHTML attribute of that object (depending on browser - IE requires .text) to the fetched source. So far I've tested it in IE 6 and FF 1.5.
Usage for including "/script/myscript.js":
Note: in reality, the include() call would be done from inside another .js file.
<head>
<script language="Javascript" src="ScriptManager.js" type="text/javascript"></script>
<script language="Javascript" type="text/javascript">
ScriptManager.script_base_link = '/script'; //set up our base link
//ScriptManager.script_file_extension = '.js'; //defaults to .js
ScriptManager.ErrorHandler.silent = false; //set to true or remove in production
try {
ScriptManager.include( 'myscript' );
}
catch (e) {
ScriptManager.ErrorHandler.handle_error( e );
}
</head>
And that's all.
The code for ScriptManager.js is below.
Copy & paste this into ScriptManager.js:
function ErrorHandler() {
}
ErrorHandler.handle_error = function ( e ) {
try {
ErrorHandler.show_error( e.message );
}
catch(e) {
}
}
ErrorHandler.show_error = function( message ) {
try {
if ( !ErrorHandler.silent ) {
alert( message );
}
}
catch(e) {
}
}
function HTTPRequest() {
//
// Properties
//
this.request_object = null;
this.async = true;
this.onreadystatechange = null;
//
// Methods
//
this.get_request_object = get_request_object;
this.send = send;
this.is_busy = is_busy;
this.abort = abort;
this.get_readyState = get_readyState;
this.get_status = get_status;
this.get_responseText = get_responseText;
function get_request_object() {
try {
if ( !this.request_object ) {
var http_request;
if ( typeof(XMLHttpRequest) != 'undefined' ) {
http_request = new XMLHttpRequest();
}
else {
try {
http_request = new ActiveXObject('Msxml2.XMLHTTP');
}
catch(inner_e) {
try {
http_request = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(inner_e2) {
}
}
}
this.request_object = http_request;
}
return this.request_object;
}
catch(e) {
throw e;
}
}
function get_readyState() {
try {
if ( request_obj = this.get_request_object() ) {
return request_obj.readyState;
}
return null;
}
catch( e ) {
throw e;
}
}
function get_status() {
try {
if ( request_obj = this.get_request_object() ) {
return request_obj.status;
}
return null;
}
catch( e ) {
throw e;
}
}
function get_responseText() {
try {
if ( request_obj = this.get_request_object() ) {
return request_obj.responseText;
}
return null;
}
catch( e ) {
throw e;
}
}
function send( which_url ) {
try {
var http_request_obj;
if ( !(http_request_obj = this.get_request_object()) ) {
throw 'Your web browser does not support this function.';
}
if ( this.is_busy() ) {
this.abort();
}
if ( this.onreadystatechange ) {
http_request_obj.onreadystatechange = this.onreadystatechange;
}
http_request_obj.open("GET", which_url, this.async);
http_request_obj.send(null);
}
catch(e) {
throw e;
}
}
function is_busy() {
try {
if ( request_obj = this.get_request_object() ) {
switch ( request_obj.readyState ) {
case 1,2,3:
return true;
break;
default:
return 0;
break;
}
}
return 0;
}
catch(e) {
throw e;
}
}
function abort() {
try {
if ( this.request_object ) {
this.request_object.onreadystatechange = null;
this.request_object.abort();
}
}
catch(e) {
throw e;
}
}
}
HTTPRequest.READYSTATE_COMPLETED = 4;
HTTPRequest.STATUS_OK = 200;
////
//// ScriptManager
////
function ScriptManager() {
}
ScriptManager.include = function( file_name ) {
try {
var file_path;
var head;
var body;
var request = new HTTPRequest();
var script_obj;
script_obj = document.createElement('script');
script_obj.setAttribute('type', 'text/javascript');
if ( !ScriptManager.has_script_file_extension(file_name) ) {
file_name = file_name + ScriptManager.script_file_extension;
}
file_path = ScriptManager.script_base_link + '/' + file_name;
request.async = false;
request.send( file_path );
if ( typeof(script_obj.text) != 'undefined' ) {
script_obj.text = request.get_responseText();
}
else if ( typeof(script_obj.innerHTML) != 'undefined' ) {
script_obj.innerHTML = request.get_responseText();
}
if ( head = document.getElementsByTagName('head')[0] ) {
head.appendChild(script_obj);
}
else if ( body = document.getElementsByTagName('body')[0] ) {
body.appendChild(script_obj);
}
else {
throw 'ScriptManager::include requires a or tag';
}
}
catch ( e ) {
ScriptManager.ErrorHandler.handle_error(e);
}
}
ScriptManager.has_script_file_extension = function( file_name ) {
try {
var ext = ScriptManager.script_file_extension;
if ( ext ) {
if ( file_name.substring(file_name.length - ext.length, file_name.length) == ext ) {
return true;
}
}
return 0;
}
catch ( e ) {
throw e;
}
}
ScriptManager.script_base_link = '';
ScriptManager.script_file_extension = '.js';
ScriptManager.ErrorHandler = ErrorHandler;
ScriptManager.ErrorHandler.silent = true;