IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

とてもシンプルに自分自身が属する script 要素を取得

グローバル領域に以下の一行を書く

<script>
var currentScript = (function (e) { if(e.nodeName.toLowerCase() == 'script') return e; return arguments.callee(e.lastChild) })(document);

alert(currentScript);
</script>

こうすることで、currentScript はこの script 要素を指す。

いちおう説明

DOM は構築されるときに、上から順番に構築される。そして、script タグがあると、 script 要素を構築したあとに、スクリプトを実行する。
つまり、スクリプトが実行されたとき script 要素は今まさに作られたばかりであり、それよりも後ろの要素が存在しない。さらにこの script 要素を含むすべての要素が 今まさに構築中の状態で document から lastChild をたどって行けば必ずたどり着くのである。

たとえば、以下のような HTML があったとすると

<html>
  <script>
    // このスクリプトが実行される時点ではこの script 要素は
    // document.lastChild.lastChild である。
  </script>
  <head>
    <script>
      // このスクリプトが実行される時点ではこの script 要素は
      // document.lastChild.lastChild.lastChild である。
    </script>
  </head>
  <body>
    <script>
      // このスクリプトが実行される時点ではこの script 要素は
      // document.lastChild.lastChild.lastChild である。
    </script>
  </body>
  <script>
    // このスクリプトが実行される時点ではこの script 要素は
    // document.lastChild.lastChild である。
  </script>
</html>

ということである。

これを利用すると

script タグを張りつけた位置の回りを操作するということが簡単に出来そうである。

例えば:前のタグを消す
// hidden.js
var currentScript = (function (e) { if(e.nodeName.toLowerCase() == 'script') return e; return arguments.callee(e.lastChild) })(document);

var prevTag = (function(e){ if(e.nodeType == 1) return e; return arguments.callee(e) })(currentScript.previousSibling);
prevTag.style.display = 'none';
<div>秘密だよー><</div><script src="hidden.js"></script>

とかとか

追記: prototype.js 1.5 系ならたぶんこうかな。(未確認)

Element.recursivelyCollect(document, 'lastChild').last();