jiichan.com

PROGRAMMING

javascript
CSS
PHP
Java

jsファイルからjsファイルを呼び出す

javascriptの外部ファイルはhtmlのhead内に<script>タグを記述し呼び出しますが、 ある条件のときだけ呼び出ししたい場合があります。
そこで「javascriptファイルからjavascriptファイル を呼び出す」方法を考えます。
呼び出す側のファイルはcall.jsでindex.htmlにスクリプトタグがあり、呼び出される側のファイルはinclude.jsで内容は次のとおりです。

【 index.html 】

<head>
	<script src="jquery-1.8.0.min.js"></script>
	<script src="call.js"></script>

【 include.js 】

var resText="this is include.js";

方法その1:document.writeでscriptタグを書き込む

document.writeメソッドはスクリプトから文字列やタグを出力するために使いますが、 このメソッドを利用しscriptタグを出力します。
ただ、writeメソッドをonloadイベント内に書き込むと、ページの出力が完了した後に実行されるので 出力されたページを上書きします。結果としてスクリプトタグだけの出力になり、何もない真っ白いページ になってしまうので注意が必要です。

document.write("<script type='text/javascript' src='include.js'></script>");

window.onload = function(){alert(resText);};

document.writeメソッドをonloadの外に記述し、include.js内のスクリプトタグができた後、つまりぺージの 読み込みが完了した後にonloadでinclude.js内の変数の値を表示しています。

方法その2:DOMで要素ノード(scriptタグ)を追加する

DOMを利用して要素ノード(scriptタグ)を追加します。
この場合もスクリプトタグが出来上がってからonloadで変数の内容を呼び出しています。

var script = document.createElement("script");
// 要素ノードの属性値設定、HTML5はtypeプロパティは不要
script.src = "include.js";
var head = document.getElementsByTagName("head");
head[0].appendChild(script);

window.onload = function(){alert(resText);};

方法その3:タグ追加+タイマーを使う

前の方法1と方法2はinclude.jsの読み込み完了後に処理するためにonloadを使っています。 onloadを使わずにタイマーを使ってinclude.jsの読み込み完了をチェックし、完了後にinclude.js 内の変数resTextを表示してみます。

// include.jsを読み込む前のスクリプトタグの数
var count = document.getElementsByTagName("script").length;

var script = document.createElement("script");
script.src = "include.js";
var head = document.getElementsByTagName("head");
head[0].appendChild(script);

setTimeout(function() {
	// タグの数が増えていない場合は読み込みが完了していない
	if(document.getElementsByTagName("script").length == count) {
		// 自身を再起呼び出し
		setTimeout(arguments.callee, 100);
	}else{
		alert(resText);
	}
}, 100);

こちらで、 読み込み完了のチェックに要素の数を使うという発想に感心しました。

方法その4:XMLHttpRequestを使う

javascriptの HTTP通信機能であるXMLHttpRequestを使ってinclude.jsの中身をテキストで取得し、 それをeval関数でjavascriptのコードとして実行します。

// このコードはIE7以降有効です
var req = new XMLHttpRequest();
req.open("GET", "include.js", false);
req.send("");

// 上のreq.openでは同期通信(false)を指定しているので以下はレスポンスを待ってから実行される。
// 文字列をjavascriptとして実行。
eval(req.responseText);
 
alert(resText);

方法その5:jQueryでAjaxを使う

方法4でXMLHttpRequestを同期通信で利用したので、方法5ではjQueryでAjax(非同期)を使います。

// GETリクエストでjavascriptファイルを読み込みコールバック関数で実行
$.getScript("./include.js", function(){
	// 読み込まれたjavscriptをいろいろ使う
});

// あるいは
$.ajax({
	url: "./include.js",
	type: "GET",
	dataType: "script"
}).done(function(data) {
// 文字列をjavascriptとして実行。
	eval(data);
	// 読み込まれたjavscriptをいろいろ使う
});

IE7以降は、XMLHttpRequestの実装が殆どのブラウザで済んでいるので、方法4とコード量はあまり変わりがありません。 しかし、今は「何をするにもjQuery」?でライブラリも必ず読み込んでいるし、この方法にすることにしました。

結論:どれを使うか?

方法1と方法2ではjavascript実行タイミングの問題からかwindow.onloadを使わなければ alert(resText)が未定義になったり、うまく機能しませんでした。
方法3はコードが少し長めですが、発想のすばらしさに感心しました。また汎用性もあると思います。
やはり方法4や方法5のようにXMLHttpRequestの使用が簡単で使いやすいと思います。
JSONPを使うときのようにコールバック関数も考えましたが、include.jsを書き換えることになるので除外しました。 HTML5にFileSystemというのがあるが、各ブラウザの実装の問題や、ファイルを自由に選択できない などの問題もあり論外でした。