A Better Project@はてなダイアリー(インポート版)

基本的にここは更新されません。詳細はaboutへ。

IEでDOMで生成したbutton(input要素)のイベントハンドラ(onClick)が正常に動作しない

2006-10-24追記:解決策を含めた続編をd:id:potappo:20061024:1161651356に書きました。
なんかわかりにくい(もう少し専門的言い方があるのかも)ので、軽く説明。

ブラウザ上で訪問者に何らかのスクリプトを実行させるボタンを表示させる方法の一つとして、HTMLファイルに、HTMLでtype="button"を属性として指定したinput要素を記述する方法があります。押したときに実行されるスクリプトイベントハンドラ属性であるonClick属性に指定します。以下にサンプルページ1の簡略したソースを示します。2006-10-25追記:サイト移転したため、現在のサンプルページとはやや異なる部分がありますが、そのままにしておきます。以下、同様。

headや宣言は省略・・・
<body>
<h1>HTMLで記述した例</h1>
 <form>
  <input type="button" value="OK" onclick='alert("sample");' />
 </form>
以下略

サンプルページ1へのリンク(ボタンを押すと「sample」と書かれたダイアログが表示されます)。

これを「HTMLで記述したbutton」とします。「HTMLレンダリングエンジンで生成したbutton」と呼んでも良いかもしれません。

JavaScriptとDOMを使うと、HTMLファイルにinput要素を記述しなくても、このbuttonをブラウザ上に表示させることが出来ます。
以下にサンプルページ2の簡略したソースを示します。

宣言とか略・・・
<script type="text/javascript" src="sample01.js"></script>
</head>
<body onload = MakeInput();>
<h1>DOMで生成した例</h1>
</body>
</html>

以下が、sample01.jsのソースの一部分。

function MakeInput(){//DOMを使ってinput要素を生成する関数
	var theBody = document.getElementsByTagName("body")[0];//body要素を取得
	var myform = document.createElement("form");//form要素を生成
	var myinput = document.createElement("input");//input要素を生成
	//新たなinput要素にtype、value、onClickの各属性を追加。
	myinput.setAttribute('type', "button");
	myinput.setAttribute('value', "OK");
	myinput.setAttribute('onclick', 'alert("sample");');
	myform.appendChild(myinput);//form要素にinput要素を追加。	
	theBody.appendChild(myform);//body要素にform要素を追加。
	さらにリンクを生成しているが略・・・。
}

サンプルページ2へのリンク。

これを「DOMで生成したbutton」とします。

サンプルページ1とサンプルページ2はソースとリンク先などの違いはあれど、ブラウザでは同じように表示されるはずです。表示は別にIEでも問題ないはずです。

ところが。

Firefox1.5.0.1日本語版とOpera8.54日本語版(両方ともWindows版)では、ボタンを押すと、サンプルページ1と同様に「sample」と書かれたダイアログが表示されるのですが(私の環境ではそうなります)が、IE6 (WindowsXP Home SP2) でサンプルページ2のボタンを押しても、何も起こりません。これは明らかにIEのバグではないでしょうか。

本当は、「IEにおいて、DOMで生成したinput要素のvalue値はJavaScriptでは全く参照できない」とかいうタイトルにしようとしたんですが(実際には、HTMLで記述したイベントハンドラでならば、問題なく参照できます)、検証サンプルを作るうちにどんどん問題が一般化してしまってちょっとびっくりです。

IEのDOM実装の悪さにはもう本当に疲れました。こんな時間に更新することはもう2度とないです。