IDを持つDOMツリー要素はグローバル変数になりますか?
-
26-09-2019 - |
質問
シンプルなHTMLELEMENTラッパーのアイデアに取り組んでいます。インターネットエクスプローラーのために以下をつかみました クロム:
DOMツリーにIDを使用した特定のHTMLelementの場合、IDを使用してVIVを変数名として取得することができます。だからdivのような
<div id="example">some text</div>
の インターネットエクスプローラー8 そして、あなたができるクロム:
alert(example.innerHTML); //=> 'some text'
また
alert(window['example'].innerHTML); //=> 'some text'
だから、これは意味しますか DOMツリーのすべての要素 グローバルネームスペースの変数に変換されますか?また、これを代替品として使用できることも意味しますか getElementById
これらのブラウザの方法?
解決
起こるはずのことは、「名前付き要素」が明らかな特性として追加されていることです document
物体。これは本当に悪い考えです。要素名が実際のプロパティと衝突することを可能にするので document
.
つまり、名前の要素をのプロパティとして追加することで、状況を悪化させました window
物体。これは、どちらかのメンバーの後にあなたの要素を命名することを避けなければならないので、これは二重に悪いです document
または window
オブジェクト(またはプロジェクト内の他のライブラリコード)を使用することをお勧めします。
また、これらの要素がグローバルな変数として表示されることを意味します。幸いなことに、この場合は実際のグローバルです var
また function
あなたのコードの宣言はそれらを影で覆うので、ここで名前を付けることについてそれほど心配する必要はありませんが、衝突した名前のあるグローバル変数への割り当てをしようとすると、それを宣言するのを忘れている場合 var
, 、IEが要素自体に値を割り当てようとするため、IEでエラーが発生します。
一般に、省略するのは悪い習慣と考えられています var
, 、で見える名前の要素に依存するだけでなく window
またはグローバルとして。に固執します document.getElementById
, 、これはより広く支持され、あいまいではありません。タイピングが気に入らない場合は、名前の短い名前で些細なラッパー関数を書くことができます。いずれにせよ、ブラウザが通常最適化するため、ID-to-Element Lookup Cacheを使用することには意味がありません getElementById
とにかくクイックルックアップを使用するために呼び出します。あなたが得るのは、要素が変わるときの問題だけです id
またはドキュメントから追加/削除されます。
OperaはIEをコピーし、その後WebKitが参加しましたが、今では以前に標準の要素を置くという事前に標準化された実践の両方が参加しました document
プロパティ、およびそれらを装着する以前の練習の練習 window
それは であること 標準化 HTML5は、ブラウザの著者によって私たちに与えられたあらゆる恐ろしい実践を文書化し、標準化することであり、それらを永遠にWebの一部にします。したがって、Firefox 4もこれをサポートします。
「名前付き要素」とは何ですか?と何でも id
, 、およびaで何でも name
「識別」の目的に使用される:つまり、フォーム、画像、アンカー、その他いくつかは、他の無関係なインスタンスではありません。 name
属性、フォーム入力フィールドのコントロール名のように、パラメーター名 <param>
またはメタデータタイプイン <meta>
. 。 「識別」 name
sは、賛成して避けるべきです id
.
他のヒント
以前の答えで述べたように、この動作は ウィンドウオブジェクトの名前付きアクセス. 。の値 name
いくつかの要素の属性との値 id
すべての要素の属性は、グローバルのプロパティとして利用可能になります window
物体。これらは名前が付けられた要素として知られています。以来 window
ブラウザ内のグローバルオブジェクトであり、各名前の要素はグローバル変数としてアクセスできます。
これはもともとInternet Explorerによって追加され、最終的には、この動作に依存するサイトとの互換性のために、他のすべてのブラウザーによって実装されました。興味深いことに、Gecko(Firefoxのレンダリングエンジン)はこれを実装することを選択しました 癖モード のみ、他のレンダリングエンジンは標準モードでそれを残しました。
しかし、Firefox 14のように、 Firefoxは、名前のAccessをサポートするようになりました に window
標準モードのオブジェクトも同様です。なぜ彼らはこれを変えたのですか?標準モードでこの機能に依存するサイトがまだたくさんあることがわかりました。マイクロソフトも マーケティングデモをリリースしました それは、DemoがFirefoxで動作するのを防ぎました。
WebKitが最近持っています 反対と見なされました, 、名前の名前を委ねます window
癖モードのみにオブジェクトします。彼らはGeckoと同じ理由でそれに反対しました。
だから…この振る舞いは今のように見えるのでクレイジー 技術的には、標準モードのすべてのメジャーブラウザの最新バージョンで使用できます. 。しかし、名前付きアクセスはやや便利に思えるかもしれませんが、 使用しないでください.
なんで?この記事では、理由の多くを要約することができます。 グローバル変数は悪いです. 。簡単に言えば、余分なグローバル変数をたくさん持っていると、より多くのバグにつながります。あなたが誤っての名前を入力したとしましょう var
そして、たまたまタイプAn id
DOMノードの、驚き!
さらに、標準化されているにもかかわらず、ブラウザの名前付きアクセスの実装にはまだかなりの矛盾があります。
- つまり、誤って値を作成します
name
フォーム要素(入力、選択など)にアクセスできる属性。 - GeckoとWebKitは間違っていません
<a>
タグを介してアクセス可能ですname
属性。 - Geckoは、同じ名前の複数の名前の要素を誤って処理します(参照の配列ではなく、単一のノードへの参照を返します)。
そして、あなたがエッジケースで名前のAccessを使用しようとするならば、私はもっとあると確信しています。
他の回答で述べたように、使用します document.getElementById
DOMノードへの参照を取得するには id
. 。ノードへの参照を取得する必要がある場合 name
属性の使用 document.querySelectorAll
.
サイトで名前のAccessを使用して、この問題を伝播しないでください。非常に多くのWeb開発者がこれを追跡しようとして時間を無駄にしてきました 魔法の 行動。実際にアクションを実行し、レンダリングエンジンを標準モードで名前のアクセスをオフにする必要があります。短期的には、悪いことをしているサイトが壊れますが、長期的にはWebを前進させるのに役立ちます。
あなたが興味を持っているなら、私は私のブログでこれについてもっと詳細に話します - https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/.
あなたは固執する必要があります getElementById()
これらの場合、たとえば:
document.getElementById('example').innerHTML
つまり、要素を混ぜるのが好きです name
と ID
グローバルネームスペースの属性は、あなたが取得しようとしているものを明確にするのが最善です。
はい、彼らがやります。
Chrome 55、Firefox 50、IE 11、IE Edge 14、およびSafari 10でテスト
次の例で:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="im_not_particularly_happy_with_that">
Hello World!
</div>
<script>
im_not_particularly_happy_with_that.innerText = 'Hello Internet!';
</script>
<!-- Looking at you W3 HTML5 spec group ಠ_ಠ -->
</body>
</html>
質問は、「提供されたIDを含むHTMLタグはグローバルにアクセス可能なDOM要素になりますか?」
答えはイエスです!
それがそれが機能することを意図していた方法であり、だからこそ、IDはW3Cによって最初に導入されました。解析されたスクリプト環境のHTMLタグのIDは、対応するDOM要素ハンドルになります。
しかし、Netscape Mozillaは(侵入する)W3Cに適合することを拒否し、頑固に非推奨の名前属性を使用してHAVOCを作成し、したがって、Scripting機能とW3Cの一意のIDの導入によってもたらされるコーディングの利便性を破りました。
Netscape Navigator 4.7 Fiascoの後、開発者全員がW3Cに侵入しましたが、アソシエイトは間違ったプラクティスと誤用の例でWebに取って代わりました。既に控えめな名前属性の使用と再利用を強制する[!これは一意ではありませんでした] ID属性と同等に、特定のDOM要素にアクセスするためにIDハンドルを使用するスクリプトが単純に壊れるようにします。
また、彼らはまた、広範なコーディングのレッスンと例を書いて公開するようにしました[彼らのブラウザはとにかく認識しません document.all.ElementID.property
それ以外の ElementID.property
少なくともそれを非効率的にし、ブラウザに同じトークンを使用して(現在[1996-97]、削除された)名前と標準ID属性を提供することで、HTMLドメインで単純に壊れなかった場合に備えて、ブラウザにより多くのオーバーヘッドを与えるために同じトークン値。
彼らは、ID属性がより短く、したがって、古代の名前のプロパティよりもバイトセービングでコーダーにとってより便利であることを除いて、名前とIDが実際に同じであることを、当時の - 当時の無知なコード作成アマチュアの圧倒的な軍隊を容易に納得させることができました。もちろん嘘でした。または - HTMLの公開された記事に取って代わって、スクリプトエンジンがアクセスできるようにタグに名前とIDの両方を提供する必要があることを説得する記事を説得します。
モザイクキラー[コードネーム「モジラ」]は非常に腹を立てていました。
一方、Rising Microsoftは非常に素朴でした。彼らは、削除名プロパティのために非推奨を維持し、マークされ、それが一意の識別子であるIDであるかのようにそれを扱うべきであると考えていたので、 Netscapeの研修生がコーディングした古いページ。彼らは致命的でした...
また、IDに矛盾する要素の配列コレクションを返すことは、この意図的な人為的な問題の解決策でもありませんでした。実際、それは全体の目的を打ち負かしました。
そして、これがW3Cが醜くなって、私たちに愚かさを与えた唯一の理由です document.getElementById
そして、それに伴うrococoのgoddamn迷惑な構文...(...)