今天寫程式時遇到一個問題,我希望動態載入一個語言檔(因為不同使用者可能會使用不同的語言),然而如果我異步地載入的話,可能語言檔未載入好就需要用了,那當然會出現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 : , , , , , ,
Categories : javascript