今天寫程式時遇到一個問題,我希望動態載入一個語言檔(因為不同使用者可能會使用不同的語言),然而如果我異步地載入的話,可能語言檔未載入好就需要用了,那當然會出現runtime error。當然,我可以加入callback function,當語言檔載入好才執行callback function,那就可以解決runtime error,然而這樣寫的話程式碼會很不整潔,違反西杰寫程式的原則:)。
動態載入script檔,一般會使用的方法是利用DOM創造一個script node,然後把script node加入至head node之中,瀏覽器就會載入src的script檔。
var load = function (scriptName){
var script = document.createElement(”script”);
script.type = “text/javascript”;
script.src = scriptName;
document.getElementsByTagName(”head”)[0].appendChild(script);
}
在Google的第一個結果中就建議了使用這種方法來動態載入script檔,要加入callback function很簡單
var load = function (scriptName, callback){
var script = document.createElement(”script”);
script.type = “text/javascript”;
script.src = scriptName;
script.onload = callback;
document.getElementsByTagName(”head”)[0].appendChild(script);
}
那麼當載入script檔完成後就會執行callback的function了。然而,這種寫法會令我的程式加多很多不必要的程式碼,而且亦因為使用callback function,這會令到callback function中的程式碼改變了scope,也不是一個好的OOP編程風格,於是我就想到了要用同步載入script檔來解決此問題。
要同步載入script檔,我的方法是利用AJAX(XHR)來實現,正確來說是SJAX,也就是利用XHR來發出要求,再eval載入了的script檔。
var load = function (scriptName){
var req = new XMLHttpRequest;
req.open(’GET’, scriptName, false);
req.send(null);
if (req.status == 200)
window.eval(req.responseText);
}
這個版本不支援I.E.,但是要改成I.E. compatible並不困難,主要就是差在XHR的Object而已。理念是利用XHR同步要求的特性,阻止javascript的執行,就可以解決需要的script檔比現行script檔遲載入以致的runtime error了。
Tags : AJAX, callback, dynamic load script, XHR, 動態載入, 同步, 異步
Categories : javascript