兩種動態加載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。