自身の所属するオブジェクトを調べる再考

昔、document.scriptsを利用したら最初から用意されているから便利でfxでは自分で実装しちゃぇみたいなエントリ書きましたがSafari2で挫折。

Safari2だと

document.scriptsがあるにはあるけどなんちゃって実装(?)みたいで。document.scriptsの値がいつになっても変化せず。そして上書きもできず。

<html>
<head>
<script type="text/javascript">
    alert(document.scripts.length); // 0
</script>
</head>
<body>
<script type="text/javascript">
    alert(document.scripts.length); // 0
</script>
<script type="text/javascript">
    alert(document.scripts.length); // 0
</script>
</body>
</html>

結局

というわけで大人しく以下のコードで決着。これを任意の<script>に入れればJSで自分自身の取得するオブジェクトが取得可能。

var scripts = document.getElementsByTagName('script');
var script = scripts[scripts.length - 1];
<html>
<head>
<script></script>
</head>
<body>
<script id="foo">
    var scripts = document.getElementsByTagName('script');
    var script = scripts[scripts.length - 1];
    alert(script.id); // foo
</script>
<script></script>
</body>
</html>

Tipsとして

document.getElementsByTagName('script')で取得してfor利用して取得する方法。ファイル名を固定してそのファイル名をルックアップして自身のscriptオブジェクトを探すというテクがありますが…。

var scripts = document.getElementsByTagName('script');
// -- A
for(i=0;i<scripts.length;i++){
    // ここで処理する。
};
// -- B
for(f=scripts.length-1;0<=f;f--){
   // ここで処理する。
};

Bパターンにしたほうがいろいろと早いと思う。

なにに使える。

そもそも。自身の所属するオブジェクトを調べるなんて分かったよう分らないタイトルなんですが、例えば以下のように外部js読み込みの際にクエリ渡してそのクエリを元に条件分岐などしたいときなどに利用できたりする。

<script src="foo.js?hoge"></script>
var scripts = document.getElementsByTagName('script');
var uri = scripts[scripts.length - 1].src;
var query = uri.slice(uri.indexOf('?') + 1);
document.write(query); // queryの中身はhogeになる。