document.writeハック

ハックその1

document.write = function()
{
    var arg = [];
    var scripts = document.scripts;
    for(var i=0,f=arguments.length;i<f;i++){
        arg[i] = arguments[i];
    };
    scripts[scripts.length-1].insertAdjacentHTML('beforeBegin', arg.join(''));
};
効用

上記ハックを実施するとdocument.createElement('script')で動的にscript要素を追加してもdocument.writeされる。補足ですが、document.createElement('script')で動的にscript要素を追加してもやはりdocument.scriptsの最後に追加されます。つまり、document.scripts[document.scripts.length-1]で取得できるということ。

サンプル
注意点

オリジナルのdocument.writeとはノード構築順番がずれます。scriptエレメントにはinsertAdjacent系ではafterBeginやafterEnd系で挿入してもエレメントが無視されてしまうみたい。DOMツリーはFirebugで確認した。

<!--オリジナルのDOMツリーの状態-->
<script>
   <a href="hoge.html">foo</a>
   <span>bar</span>
</script>
<!--ハック適用後のDOMツリーの状態-->
<a href="hoge.html">foo</a>
<span>bar</span>
<script></script>

ハックその2

(function()
{
    var buffers = {};

    document.write = function()
    {
        var length = document.scripts.length - 1;
        if(!buffers[length]){
            buffers[length] = new String.Buffer();
        };
        buffers[length].append.apply(null, arguments);
    };

    document.flush = function()
    {
        for(var i in buffers){
            document.scripts[i].insertAdjacentHTML('beforeBegin', buffers[i].toString());
        };
        buffers = {};
    };
})();
効用

document.writeした結果を任意のタイミング(document.flushを利用するタイミング)でDOMの描画を開始させることができる。String.Bufferはhttp://www.openjsan.org/doc/s/sh/shogo4405/String/Buffer/からダウンロード。

なんだか

面白いハックが色々とできそうです。fxには対応には標準では対応してないんですが対応させる為のエントリも書いてますので関連項目も必要とあれば参照下さい。