innerHTMLでscriptする

innerHTMLにscriptを代入しても評価されず無視されるのはIEの仕様なのでいいとしてその回避策。最近、昔あの方法で出来たんだけどいつの間にかできなくなってるコードが出てきている気がします(気のせいにしておこう)。

以下は一般的な動かないコード。
<div id="foo"></div>
<script type="text/javascript">
document.getElementById('foo').innerHTML = "<script type='text/javascript'>alert('動かない')<"+"/script>";
</script>
以下は動くコード。
<div id="foo"></div>
<script type="text/javascript">
document.getElementById('foo').innerHTML = "&nbsp;<script type='text/javascript' defer='defer'>alert('動くよ')<"+"/script>";
</script>

ポイントなのは<script>の前に&nbsp;でも"A"や"B"でもなんでもいいからscript以外のノードをつくっておくこと(1つ目)。加えてscript属性にdefer="defer"を指定あげること(2つ目)。以上の2つのポイントを守ればinnerHTMLでscriptできるようです(IE6+WinXP)で確認。

scriptのdefer属性

script内にdocument.writeなどがないことを前提にscript要素の中身を遅延評価してHTMLレンダリング速度を向上させるときに利用します。本当にはやくなるのかは不明です…。MSDN内のDHTML Dude:更なるパフォーマンス向上のヒントでdeferを利用した高速化テクの記載有ます。

追記

MSDNのinnerHTMLの仕様(Microsoft API and Reference Catalog)みていたらRemarksの中に

When using innerHTML to insert script, you must include the DEFER attribute in the script element.

和訳するとinnerHTMLの中にscriptを挿入したければscript要素にdefer属性を入れなさい><ってな具合です。というわけでこれは仕様らしいです。初めて知りましたw