外部JSファイルの動的読み込み
外部JSファイルを任意のタイミングで読み込みたいとき、scriptタグを生成してdocumentに追加すればロードしてくれます。
function loadScript(src, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = src;
head.appendChild(script);
callback();
}
loadScript("path/to/script.js", function() {
console.log('script loaded');
});
ただし、読込みが終わった順に実行されるため、
上記の様にコールバック関数を設定しても追加したスクリプトよりも先にコールバックが実行されてしまいます。
そこで、scriptを読み込み完了後にコールバックが実行されるように修正します。
function loadScript(src, callback) {
var done = false;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = src;
head.appendChild(script);
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
if ( !done && (!this.readyState ||
this.readyState === "loaded" || this.readyState === "complete") ) {
done = true;
callback();
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
if ( head && script.parentNode ) {
head.removeChild( script );
}
}
};
}
loadScript("path/to/script.js", function() {
console.log('script loaded');
});
script.onload
にコールバックを設定してもいいのですが、IE8以下で正しく動作しません。
script.onreadystatechange
のreadyStateプロパティを監視してコールバックを設定することでIEでも正常に動作させることが出来ます。
scriptタグの中に文字列を追加して動的に実行
var scripts = [
"console.log(1);",
"console.log(2);",
"console.log(3);",
"console.log(4);"
];
var head = document.getElementsByTagName('head')[0];
for (var i = 0, l = scripts.length; i < l; i++) {
var script = document.createElement('script');
script.text = scripts[i];
head.appendChild(script);
}
script.innerHTML
ではなくてscript.text
な点がミソ。
こちらもIE8以下ではinnerHTMLは正しく動かず、代わりにtextプロパティに設定することで正常に動作させることが出来ます。