2007年11月17日 14:30 [Edit]

javascript - 添削 - DOM時代のdocument.write()

その他不具合を直してみました。

404 Blog Not Found:javascript - DOM時代のdocument.write() - zorioさんのコメント
これだと、同じ親の下に複数のdocument.writeがあっても、最初の所に全部書き出されてしまいます。

結論からいうと、以下のとおりとなりました。FireFox, Safari, Operaで検証済み。IEはいかがでしょうか?。

document.getCurrentScript = function(){
    return (function (e) {
      if (e.nodeName.toLowerCase() == 'script') return e;
      return arguments.callee(e.lastChild)
    })(document)
};

if (!document.__builtin__) document.__builtin__ = {};
document.__builtin__.write = document.write;

document.write = function (what, where) {
  if (!where) where = this.getCurrentScript();
  var here = where.previousSibling;
  if (!here || here.nodeType != 1 || here.getAttribute('class') != '.written'){
    here = document.createElement('div');
    here.setAttribute('class', '.written');
    where.parentNode.insertBefore(here, where);
  }
  if (what.nodeType){
    here.appendChild(what);
  }else{
    if (what.match(/^<script/i)){
      document.write = document.__builtin__.write;
      document.write(what);
      // document.write = arguments.callee;
    }
    else{
      here.innerHTML += what;
    }
  }
};

テスト

あいうえお
かきくけこ
あいうえお<br>
<script>
document.write(1.0 + '<br>');
document.write(1.1 + '<br>');
document.write('<'+'script'+'>' + 'document.write(3.0+\'<br>\')' +'</'+'script'+'>')
document.write(4.0 + '<br>');
</script>
かきくけこ<br>
<script>
document.write(2.0 + '<br>');
document.write(2.1 + '<br>');
</script>

解説

以前のコードよりすっきりしています。まず書き込み対象のnodeが無条件にpreviousSiblingになりました。最初の一回だけ、<div class=".written">なnodeを追加するのは前と同じですが、このnodeがあるかどうかの判定を変更しています。

しかし、これだけだとdocument.writeの中で<script>タグを追加してその中でまたdocument.write()するものがきちんと動かなくなります。そういう場合、組み込みのdocument.write()一時的に戻すようにしました。

面白いことに、document.__builtin__.write()を直接呼んでも駄目で、こういう書き方ならOKなのです。

こんなもんで、いかがでしょうか。

Dan the JavaScripter

追記:今度はAMNの広告もきちんと表示されてますね。

追々記: それでも、一回でもうまく行かないのがあると元に戻すというのがやはり気に食わない。別の実装を考えよう....


この記事へのトラックバックURL

この記事へのトラックバック
というわけでさらに添削。 404 Blog Not Found:javascript - 添削 - DOM時代のdocument.write() 追々記: それでも、一時的に戻すというのがやはり気に食わない。別の実装を考えよう....
javascript - 決定版 - DOM時代のdocument.write()【404 Blog Not Found】at 2007年11月17日 22:14
この記事へのコメント
動くようになりました。すばらしい。
IE7でもOKです。
http://zoriolab.info/sample/documentwrite2.html
Posted by zorio at 2007年11月17日 16:23