2012/10/17

javascriptの動的読み込み

さて、使い方を纏めてみたSyntax Highlighterですが、動的にbrushファイルを読み出すってどうやっているんだろうかと思い、ソースを追ってみました。
javascript自体良く分かっていないので調べながらです…。
  1. まず最初のpath関数は@をアドレスに置換して配列にしてSyntaxHighlighter.autoloaderメソッドに渡す。
  2. SyntaxHighlighter.autoloaderメソッド中にpreタグ内を取得して、そこからbrush名を抽出。
  3. brush名から配列のアドレスを引き出す。
  4. アドレスを元にHTMLScriptElementオブジェクトを作成、読み込み完了時に動作するように、onloadに関数を設定。
  5. bodyにappendChildメソッドで追加。
なるほど、ページ書き換えで<script src="~" type="text/javascript"></script>を付け足す感じなんですね。

書き換えただけでは、読み込んでくれないのでは?と思いましたが、大丈夫のようです。

試しに実験してみました。

まず外部スクリプトとして、以下のファイルを作成。
function test()
{
  alert("test");
}
そして、表示しているページで以下のスクリプトを実行。
  <script type="text/javascript">
    var script = document.createElement('script');
    script.src = 'js1.js';
    script.type = 'text/javascript';
    script.language = 'javascript';
    script.onload =  function()
    {
      test();
    };
    document.body.appendChild(script);
  </script>
ちゃんと外部ファイルのtest()が呼ばれて、"test"とアラートが出ました。

ただし元のshAutoloader.jsのソースでは、script.onloadが以下の様になっています。
script.onload = script.onreadystatechange = function()
  {
    if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete'))
    {
      //省略      
      // Handle memory leak in IE
      script.onload = script.onreadystatechange = null;
      script.parentNode.removeChild(script);
    }
  };
調べてみると、script.onloadはIEの場合反応しないとか。

その場合、onreadystatechangeを使ってスクリプト読み込み完了時の処理をして、更にIEにはメモリリークのバグがあるので、上記のような処理を行なっているということらしいです(javascript自体を調べながらというレベルなので詳細は分かりませんが…)。

IE9で実験してみると、onloadだけでも動作したのでIEのバージョンでも違うんでしょうね。
その他の記事