兩種動態加載javascript的方法
Tue, 10 Apr 2007 20:50:41 +0800我自己是在改良網頁Isometric引擎時碰到這樣的需求(動態載入地圖),最早是用連到不同網頁避開這個問題,最近看到別人嘗試的一些方法,所以自己再試試看。
這些方法有:
- 利用document.createElement("script")來產生script node,並加到Node Tree中。
 - 利用Ajax取得.js檔案內容,並透過eval函數來執行內容。
 
經過嘗試以後,大概有了一些心得。
以下是對第一個方法的測試
主要的script:
var nav = null;
function addScript(name) {
var obj = document.createElement("script");
obj.src = name;
var target = document.getElementsByTagName("HEAD")[0];
target.appendChild(obj);
}
function test (name) {
try {
addScript(name);
setTimeout("alert(nav.getInner())", 100);
} catch (e) {
alert(e);
}
}
要載入的test1.js檔案:
var nav = {
"inner": 0,
"getInner": function () { return this.inner; }
};
測試的網頁內容:
<input type="button" value="test" onclick="test('test1.js')">
有興趣可以測試一下:第一個測試網頁連結
這個方法有幾個問題:
- 在firefox改變不會立刻生效,所以我用setTimeout來延緩測試
 - 需要對node做適當的管理,否則會佔用不必要的系統資源
 
接下來使用ajax + eval的方法。
主要的script:
var nav=null;
if (window.execScript == null) {
try {
window.execScript = function(script) {
eval(script,window);
}
} catch (e) { alert(e); }
}
function useScript (name) {
try {
var loader = xmlhttp();
loader.open('GET', name, false);
loader.send(null);
window.execScript(loader.responseText.toString());
} catch (e) {
alert(e);
}
}
function test1 (name) {
try {
useScript(name);
alert(nav.getInner());
} catch (e) {
alert(e);
}
}
function xmlhttp() 
{
try{return new ActiveXObject("Msxml2.XMLHTTP");} catch(e){}
try{return new ActiveXObject("Microsoft.XMLHTTP");} catch(e){}
try{return new XMLHttpRequest();} catch(e){}
alert("XMLHttpRequest Object not existed!!");
return null;
}
要載入的test2.js檔案:
nav = {
"inner": 3,
"getInner": function () { return this.inner; }
};
測試的網頁內容:
<input type="button" value="test" onclick="test1('test2.js')">
有興趣可以測試一下:第二個測試網頁連結
有幾個部份需要說明一下:
- 在ie上,eval沒辦法取用到global variables,所以使用window.execScript來代替,並且為firefox的window物件加上這個函數,讓兩個瀏覽器可以用同樣的方法操作。execScript的第二個參數可以省略,因為預設就是JavaScript,我這裡就偷懶不寫了。
 - eval所執行的程式,會參考到執行eval時程式的上下文,所以特別給定第二個參數為window物件,讓他可以取用global variable。