【Javascript】DOM0とDOM1を混ぜると危険?
問題
こんなことがあってびっくりしました。
1、フォーム中のあるinput要素をnameで参照する(DOM0な操作) → 参照できる
2、フォーム中のあるinput要素をremoveChild()した(DOM1な操作)
3、フォーム中のあるinput要素をnameで参照する(DOM0な操作) → まだ参照できる
動作サンプル
答え
DOM Level 1 な操作の実装は、統一されてると思うのですが、
(例 document.getElementById(), x.removeChild(y), etc.)
この、いわゆるDOM Level 0 的な操作は、
(例 document.forms[“hoge”].elements[“fuga”])
ブラウザ間で実装がまちまちで、HTML5に伴ってようやく仕様らしいものがまとまってきたと思います。
手順3で消えたはずの要素を参照できるのはおそらくIE以外です。
IE以外は以下のHTML5の仕様に従っているようです。
form[name]
Once an element has been referenced using a particular name, that name will continue being available as a way to reference that element in this method, even if the element’s actual ID or name changes, for as long as the element remains in the Document.
http://www.w3.org/TR/html5/the-form-element.html#the-form-element
フォームの要素に名前でアクセスするとき(例:document.forms[“hoge”][“fuga”] )、その名前で一度アクセスすると、その名前はその要素を参照するために利用し続けることができる。たとえその要素の名前を変更したとしても。
「Documentに残っている限り(for as long as the element remains in the Document.)」というのがどこに定義されているか気になるのですが、removeChildしてもDOMツリーから取り除かれるだけで存在はし続けていることをDocumentに残っているというのならわかります。
また removeChildではなくて、フォームのコントロール(input要素など)のnameを変更するようなスクリプトを実行しても、一度参照したことのある要素は、変わらず以前の名前で参照できるという現象が発生します。
優鬼 2022年7月23日 16:38
細かいことはわからないですが、致命的なのは
仕様書にしつこいくらい「DOMは生きている」(オブジェクトは常に最新の状態)とあるので、削除した要素が参照できたらまずいだろうと思います。
モダンなブラウザでサンプルは軒並みエラーになります。