スポンサーリンク

JavaScriptの動かないコード (中級編) scriptタグの中味を動的に書き換えた時のエラー


以下のJavaScriptコードが意図した動作をしないのは,なぜですか。(制限時間1分)

<input type="button" onClick="f()" value="「変更後」と表示">

<script language="JavaScript" id="my_script">

function f(){
	alert("変更前");
}

// 関数を定義し直す
my_script.innerHTML = "function f(){alert('変更後');}";

</script>



答え


Firefoxでは,ボタンをクリックすると,「変更前」と表示されてしまう。

IEでは,そもそも script タグの innerHTML を書き変えようとした時点でエラーになる。


Firefoxで,innerHTMLを書き換えた直後に alert( my_script.innerHTML ); してみると,ちゃんと

function f(){alert('変更後');}

と表示される。

それにも関わらず,ボタンから f() を実行した際には「変更前」と表示されてしまうのである。
my_script の内容は更新されているが,f() の内容が更新されていない。


DOM要素として「書かれている」事と,書かれた内容が「評価・実行される」事とは,別物である。

たとえ関数を定義するようなコードがscript中に書かれていても,そのコードが実行されなかったら効果は現れず,関数は定義されない。


innerHTMLを書き換えた後で

eval( my_script.innerHTML );

とすれば,現時点でscriptタグ中に書いてあるコードが評価される。
こうすれば f() の内容も更新され,ボタンを押した際には「変更後」と表示される。

コードは,あくまで実行されることが大事である。



ところで,IEではscript要素のinnerHTMLを操作できなかった。

これに加えて,IEでは,単に「要素のinnerHTMLにscriptを書く」のも未評価・未実行になる。

IEのinnerHTMLにはscriptタグを含んではダメだって
http://www.mapee.jp/wlh/ieinnerhtmlsc...

しかし,

  • innerHTML中で,scriptタグの前にスペースなど何でもいいから要素を追加しておき
  • scriptタグに defer="defer" の属性定義をしておけば

IEでも動的にscriptの中身を設定できる。

  • innerHTMLでscriptする

http://d.hatena.ne.jp/shogo4405/20061...

  • innerHTMLへscriptタグを突っ込んでscriptタグ内部のJavaScriptをキックする方法

http://d.hatena.ne.jp/GegegeMokeke/20...

これは,IEがこういう仕様なのでしょうがない。