私が使用するようになったすべてのブラウザは、id="myDiv"
を書くだけで:
myDiv
ここを参照してください: http://jsfiddle.net/L91q54Lt/
とにかく、この方法はかなり不十分に文書化されているようであり、実際、私が遭遇したソースはそれについて言及することさえせず、代わりに、
document.getElementById("myDiv")
または多分
document.querySelector("#myDiv")
そのIDが事前にわかっている(つまり、実行時に計算されていない)場合でも、DOM要素にアクセスする。後者のアプローチには、誰かが誤ってmyDiv
をより広いスコープで再定義しようとした場合(ただし、このような素晴らしいアイデアではありません...)、コードをいくつかの異なる値で上書きした場合にコードを安全に保つ利点があることがわかります。衝突に気づかずに続行します。
しかし、それ以外のことは?上記の短い形式をコードデザイン以外に使用することに懸念はありますか、それともここで何が不足していますか?
とにかく、この方法はかなり不十分に文書化されているようであり、実際、私が遭遇したソースはそれに言及すらしていません[...]
暗黙的に宣言されたグローバル変数への依存はさておき、ドキュメントがないことは、それを使用しない大きな理由です。
id
値のグローバル変数への明らかな昇格は標準に準拠しておらず( ID属性のHTML5仕様 は言及していない)、したがって、将来を想定するべきではありません。ブラウザはそれを実装します。
編集:この動作が判明 is 標準に準拠-HTML5では、window
は「名前付き要素」へのプロパティアクセスをサポートする必要があります:
上記のアルゴリズムの目的で、名前nameを持つ名前付きオブジェクトは、次のいずれかです。
- 名前が name であるアクティブドキュメントの子ブラウジングコンテキスト
- a、アプレット、エリア、埋め込み、フォーム、フレームセット、img、またはオブジェクトの要素で、値が name の名前コンテンツ属性を持つ、または
- id コンテンツ属性がname.のコンテンツ属性を持つHTML要素
出典: HTML 5仕様、「ウィンドウオブジェクトへの名前付きアクセス」 、強調mine 。
これに基づいて、標準への準拠がこのパターンを回避する理由にはなりません。ただし、仕様自体はその使用を推奨していません。
原則として、これに依存するとコードが脆弱になります。最終的にこのAPIにマッピングされるIDは、時間の経過とともに変化する可能性があります。たとえば、Webプラットフォームに新機能が追加されているためです。これの代わりに、
document.getElementById()
またはdocument.querySelector()
を使用します。
すばらしい質問です。アインシュタインはおそらく言わなかったように、物事は可能な限り単純でなければならず、単純ではないはずです。
後者のアプローチには、誰かが誤ってより広い範囲でmyDivを再定義しようとした場合(ただし、このような素晴らしいアイデアではありません...)、コードを安全に保つ利点があり、それをいくつかの異なる値で上書きし、衝突に気付かずに続行します
これが悪い考えである主な理由であり、それで十分です。グローバル変数は信頼しても安全ではありません。それらは、ページで実行されるスクリプトによっていつでも上書きできます。
さらに、myDiv
と入力するだけではdocument.getElementById()
の「短縮形」ではありません。これはグローバル変数への参照です。存在しないグローバル変数にアクセスしようとすると参照エラーがスローされるため、要素が存在しない場合はdocument.getElementById()
が喜んでnull
を返します。安全のために、try/catchブロックでグローバルへの参照をラップする必要があります。
これがjQueryが非常に人気がある理由の1つです。$("#myDiv").remove()
を実行し、myDiv
のIDを持つ要素がない場合、エラーはスローされません。コードは黙って何もしません、これは多くの場合、DOM操作を行うときに正確に必要なものです。
いくつかの理由があります。
コードとマークアップを結合したくない場合
特定の呼び出しを使用してdivにアクセスすることにより、グローバルスペースが破損することを心配する必要がありません。グローバルスペースでmyDiv
を宣言するライブラリを追加すると、修正するのが難しい苦痛の世界にいます。
DOMの一部ではない要素にIDでアクセスできます
それらは、切り離され、まだDOMに再接続されていないフラグメント、フレーム、または要素に含めることができます。
編集:ID
)によって非接続要素にアクセスする例
var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.id = "span-test";
frag.appendChild(span);
var span2 = frag.getElementById("span-test");
alert(span === span2);
私の場合、ページ内にiframeがありました。 id
属性とname
属性のどちらが原因で混乱していたのか、どちらもwindow
からアクセスできるinner_iframe
という変数に影響を与えていました。
id属性のみを使用した場合、id="inner_iframe"
のように、window.inner_iframe
はHTMLIFrameElement
になります。プロパティには inner_iframe.contentDocument
およびinner_iframe.contentWindow
ここで説明 *が含まれます
window
に現れると仮定します 受け入れられた回答で@joewが引用 :名前が値であるidコンテンツ属性を持つHTML要素
name属性のみを使用した場合、name="inner_iframe"
のように、window.inner_iframe
は「フレーム」、つまり 「ウィンドウオブジェクト」 。 contentWindow
、したがって、名前属性inner_iframeはnotにプロパティcontentDocument
またはcontentWindow
があります。
inner_iframe
変数がwindow
に表示されると想定します 受け入れられた回答で@joewによって引用されていますnameが名前であるアクティブドキュメントの子ブラウジングコンテキスト
name
とid
の両方の属性を使用し、両方の属性に同じ値を指定した場合name="inner_iframe" id="inner-iframe"
; name
属性は、id
属性を踏みにじったり覆ったりしました。 「ウィンドウオブジェクト」notHTMLIFrameElement
が残りました!したがって、私のポイントはあいまいさについて注意することです。 2つの異なるAPIを持つ同じオブジェクトのname
属性とid
属性の競合:暗黙的な動作とウィンドウ変数へのアタッチが混乱する特定のケースにすぎません。
*(および<script>
がHTMLの<iframe>
の後ろ/下にロードされた場合、または<script>
がwindow.onload
まで待機してからid属性でアクセスしようとした場合のみ)
**この「フレーム」とDOM要素の違いは、Mozillaのドキュメントでは次のように説明されています。
Window.frames疑似配列の各項目は、指定されたのコンテンツに対応するウィンドウオブジェクトを表します(i)フレームのDOM要素ではありません(つまり、window.frames [0]はdocument.getElementsByTagName( "iframe")[0] .contentWindowと同じです)。