innerHTMLでscriptタグを出力する話innerHTMLでscriptタグを出力する話

<< | コメント(1) | トラックバック(0) このエントリーを含むはてなブックマーク >>

なんらかのアクションに対して、外部ファイルを読み込みたいときってあるよねー。
Ajax的なものを作ろうとしてぶつかった沢山の壁について書いてます。

まずは表題の話。


JavascriptのinnerHTMLで<&SCRIPT>タグを表示しようとすると、なぜか何も出ない。
同じようなことをした人はみんなぶつかる壁だと思うけど、バグでもなんでもないんです。

MSのinnerHTMLの仕様にあるんですが、

When using innerHTML to insert script, you must include the DEFER attribute in the script element.
翻訳すると
スクリプトを挿入するのにinnerHTMLを使用するとき、あなたはスクリプト要素でDEFER属性を入れなければなりません。

文章そのまま、<SCRIPT>タグに「defer="defer"」を入れないといけないってことです。
要するに「マイクロソフトの仕様」でした。
※それプラス、IEのバグとして、SCRIPTタグの開始の<の前に何かスペースでいいから文字をつけないといけないかも。



まぁそれはいいんだけど、deferを入れることにより発生する弊害があるから困る。

そもそもdefer属性ってのは、処理を後回しにするための機能です。
HTML文の解析が上から順番に行われて、<SCRIPT>タグの所で処理が停止されては困る場合、
deferを入れることによって<SCRIPT>タグの解析を後回しにして、タグの先にあるHTML構文を解析します。

しかしこれは、<SCRIPT>タグ内で出力が行われない場合は正常に動作しますが、document.writeが存在すると、実行タイミングが不定なのにページへの書き込みが行われるため問題が発生します。
そのため、そもそもdeferを入れて解析を後回しにするときは、document.writeを使ってはいけないことになっています。
(これはJavaScriptの仕様です。
※ijnnerHTMlは使用可能なので、使い方次第では文字列出力も可能です。



ここから個人的な実装の話。

・外部ページを読み込んで表示する必要があるが、ActiveXオブジェクトを使いたくない。
  ↓
・innerHTMLで<SCRIPT>タグを書き込んで、タグの読込先外部ファイルの中でdocument.writeする方法を考える。
  ↓
・innerHTMLに<SCRIPT>タグタグが使用ができない(IEの仕様
  ↓
・使用するためには、deferをセットした上で、scriptタグの前に何かを描画しておく。
 例:"&nbsp;<SCRIPT type='text/javascript' defer='defer'>alert('動くよ')</script>";
  ↓
・deferはscriptの動作を後回しにするための構文で、これを入れると文字列の書き込み(document.write)が使用できない。
  ↓
・具体的には、document.writeを使用すると、ページが丸ごとリセットされてから書き込まれる。
  ↓
・なので、innerHTMLに書き込んだ<SCRIPT>タグが読み込む先のページでinnerHTMLで書き込むという方法を試す。
 具体的には、本来書き込まれるべき場所のidを渡すことによって、読込先の外部のScriptから文字列の書き込みを行う。
  ↓
・getで値を渡す際に&を使うと、innerHTMLへ入れたときにエンコードされて「&amp;」になってしまう。
 それが原因でスクリプトが止まる。(スクリプトから実行するURLに「;」が含まれていると動かんのか?)
  ↓
・ゲットつなげちまって、後からセパレートできるしかねぇな('A`)

・innerHTMLに書き込んでいるのとまったく同じスクリプト文を、普通に書いたら動くのに、書き込んでるのは動かない。
  ↓
・結論として、innerHTMlを使って埋め込んだscriptタグの中のscriptを実行するのは不可能なんじゃないか?ッツー結論にいたった。

ってことで、数時間かけてけっきょくあきらめた。
誰か成功した人いたら、おせーてくださいほんと。

トラックバック(0)

トラックバックURL: http://exe.tyo.ro/mt/mt-tb.cgi/669

コメント(1)

確認画面で、タグが全て吹っ飛びました。

もう一度書き直します。
http://d.hatena.ne.jp/shogo4405/20061210/1165819217
というdocument.write()をオーバーライドする方式を試してみましたが、
IEではうまくいきませんでした。
現実的には動的に書き換えたい箇所を
document.write()ではなく、id付き<span/>を配置し、全体をinnerHTMLした後に、
改めてidを付加した<span>に後付けでinnerHTMLするしかないと思います。
prototype.jsのeach()を使えば、
本来document.write()したかったオブジェクトの名称と<span>のidを結びつけることが可能だと思います。

コメントする

2014年10月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

月別 アーカイブ

2014年
2013年
2012年
2011年
2010年
2009年
2008年
2007年