エラー内容
<script language="javascript">
document.write(
'<input type="button" ' +
'onClick="formChange(this.form, \'hogehoge\')"' +
'value="入力欄を増やす">'
);
</script>
<noscript>
<a href="hogehoge">入力欄を増やす</a>
</noscript>
上記のように、押すたびに入力欄が増えるように設定したところ
ボタンが動かず、開発ツールに下記エラーが出ていた。
Uncaught TypeError: frm.submit is not a function
at formChange (XXX)
at HTMLInputElement.onclick (XXX)
このエラーは、HTML内で id="submit"
または name="submit"
を使っているときに発生する。
これにより、フォームの submit()
メソッドが上書きされ、JavaScript から form.submit()
を実行しようとするとエラーが出る。
原因
1. id="submit"
または name="submit"
の影響
JavaScript では、HTML の id
や name
属性で指定した名前が自動的にグローバル変数として登録される。
今回の場合、同HTML内の送信ボタンが下記のように
idがsubmitになってしまっていた。
<form id="myForm">
<input id="submit" type="submit" value="送信">
</form>
これだと、submit
はグローバル変数として定義され、フォームの submit()
メソッドを隠してしまう。
結果として、JavaScript から myForm.submit()
を呼び出すと、submit
が関数ではないと解釈されてエラーになる。
2. document.write()
の使用
サンプルコードでは document.write()
を使っているけど、これはモダンなブラウザでは避けるべき方法。これも改善が必要。
document.write() はページの読み込み中にのみ動作し、他の DOM 操作との競合が生じる可能性がある。
(しかし、今回はこの書き方を業務内で使用していたため、変更不可。)
解決方法
1. id
や name
の変更
submit
の代わりに別の名前を使う。例えば、btnSubmit
などに変更すると問題が解決する。
<form id="myForm">
<input id="btnSubmit" type="submit" value="送信">
</form>
2. document.write()
を廃止
document.write()
を使わず、代わりに DOM 操作を使ってボタンを動的に追加する方法に変更する。
DOM操作とは
DOM操作
(Document Object Model 操作)とは、
WebページのHTML要素をJavaScriptで動的に変更・操作すること。
これにより、ページの内容をリアルタイムで更新したり、新しい要素を追加したり、ユーザーのアクションに応じて反応させることができる。
例えば、ボタンを追加したり、クリックされたときに何かを表示したりすることができる。
document.getElementById
で要素を取得し、innerHTML
で内容を変更したり、appendChild
で新しい要素を追加したりできうr。
DOM操作は、ページ全体を再読み込みすることなく、必要な部分だけを変更できるため、ユーザーにとってよりインタラクティブな体験を提供できる。
DOM操作を使うとできること:
- HTML要素の取得: ページにある要素(例えば、ボタンや入力フィールド)をJavaScriptで取得。
- 要素の変更: 取得した要素の内容や属性を変更(例えば、ボタンのラベルを変更)。
- 要素の追加・削除: 新しい要素をページに追加したり、既存の要素を削除したりする。
- イベントの設定: ユーザーの操作(クリックや入力)に反応するようにイベントを設定。
例えば、document.write()
ではなく、DOM操作を使って動的にボタンを追加する場合、次のようになる:
<script>
// 新しいボタン要素を作成
var button = document.createElement("input");
button.type = "button"; // ボタンのタイプを設定
button.value = "入力欄を増やす"; // ボタンのラベルを設定
// ボタンがクリックされた時に実行する関数を設定
button.onclick = function() {
formChange(this.form, 'hogehoge');
};
// ページにボタンを追加
document.body.appendChild(button);
</script>