web-dev-qa-db-ja.com

同じid属性を持つ2つのHTML要素:本当に悪いですか?

グーグルマップのソースコードを閲覧するだけです。ヘッダーには、id = "search"の2つのdivがあり、一方には他方が含まれ、jstrack = "1"属性も持っています。それらを次のように区切るフォームがあります:

<div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...

これはグーグルなので、間違いではないと思います。

それで、このルールに違反することは本当にどれほどひどいことでしょうか? CSSとDOMの選択に注意している限り、クラスのようなIDを再利用してみませんか?誰かが故意にこれを行いますか?そうであれば、なぜですか?

128
danludwig

仕様はユニークと言う

HTML 4.01仕様 IDはドキュメント全体で一意である必要があると述べています。

HTML 5仕様 は同じことを言いますが、言い換えると。 IDはそのhomeサブツリーで一意である必要があると述べています。これは、基本的に それの定義を読む の場合のドキュメントです。

重複を避ける

ただし、HTMLレンダラーはHTMLレンダリングに関して非常に寛容なので、IDの重複を許可します。 JavaScriptでIDを使用して要素にプログラムでアクセスする場合は、可能な限り回避し、厳密に回避する必要があります。いくつかの一致する要素が見つかったときにどのgetElementById関数が返す必要があるかわかりませんか?必要があります:

  • エラーを返しますか?
  • 最初に一致する要素を返しますか?
  • 最後に一致した要素を返しますか?
  • 一致する要素のセットを返しますか?
  • 何も返さない?

しかし、たとえブラウザーが最近確実に機能しても、仕様に反しているため、将来この動作を保証することはできません。そのため、同じドキュメント内で ID を重複させないことをお勧めします。

146
Robert Koritnik

あなたは「どれほど悪い」と尋ねました。 @RobertKoritnikの(完全に正確な)答えを具体化するために...

そのコードは正しくありません。不正確は灰色の色合いではありません。このコードは標準に違反しているため、正しくありません。検証チェックに失敗しますが、失敗するはずです。

とは言っても、現在市場に出回っているブラウザはそれについて文句を言ったり、まったく問題を抱えたりすることはありません。ブラウザ彼らの権利の範囲内にあるでしょうそれについて不満を言うが、現在それらのどれの現在のバージョンのどれも現在そうしていません。これは、将来のバージョンでこのコードが適切に処理されなくなる可能性があることを意味しません。

CSSまたはJavaScriptのいずれかで、そのIDをセレクターとして使用しようとする動作は推測できず、おそらくブラウザーによって異なります。各ブラウザがそれにどのように反応するかを調べるための調査ができると思います。最良の場合、それは "class ="のように扱われ、それらのリストを選択すると思います。 (ただし、JavaScriptライブラリを混乱させる可能性があります-私がjQueryの作成者である場合は、セレクターコードを最適化して、「#」で始まるセレクターが表示された場合、単一のオブジェクトを期待し、リストは私を完全に困らせるかもしれません。)

また、最初のものを選択することもあれば、最後のものを選択することもあれば、どれも選択しないこともあり、ブラウザを完全にクラッシュさせることもあります。それを試さずに見分ける方法はありません。

「どれほど悪い」かは、特定のブラウザがHTML仕様をどの程度厳密に実装しているか、およびその仕様の違反に直面したときの動作に完全に依存します。

編集:私はたまたま今日これに遭遇しました。さまざまな種類のエンティティの検索フォームからさまざまなコンポーネントを取得して、このサイトに大きなオールインワンの優れたレポートユーティリティを作成しています。リモートページの検索フォームを非表示のdivにロードし、それらを自分のスロットに入れています。適切なエンティティタイプがレポートのソースとして選択されている場合のレポートジェネレータ。したがって、フォームの非表示バージョンと、レポートジェネレーターに表示されるバージョンがあります。付属のJavaScriptは、すべての場合において、IDによって要素を参照します。現在、ページには2つの要素(非表示の要素と表示された要素)があります。

JQueryが実行しているように見えるのは、最初の1つを選択することです。これは、すべての場合において、まさに私が望まないものです。

私は私のフィールドを取得したいページの領域を指定するセレクターを作成することでこれに対処しています(つまり:$( '#containerDiv #specificElement'))。しかし、あなたの質問に対する答えが1つあります。ChromeのjQueryは、この仕様違反に直面したとき、特定の方法で動作します。

31
Dan Ray

本当に悪いの?

  1. 泣く
  2. 無効です
  3. 多くのJavaScriptライブラリが期待どおりに機能しない
  4. それはあなたのコードを混乱させる

経験によれば、主要なブラウザのgetElementByIdは、ドキュメント内で最初に一致した要素を返します。しかし、これは将来常にそうなるとは限りません。

JQueryに#fooなどのIDが与えられると、jElementはgetElementByIdを使用し、その動作を模倣します。これを回避する必要がある場合(悲しいことです)、$( "*#foo")を使用して、jQueryにgetElementsByTagNameを使用するように説得し、一致するすべての要素のリストを返すことができます。

私はしばしば他のサイト用のコードを書かなければならず、これを回避しなければなりません。公正な世界では、IDが一意であるかどうかをチェックすることから始めるために、関数を再設計する必要はありません。 IDは常に一意である必要があります。世界は残酷で、それで私は泣きます。

22
ColBeseder

あなたはcan非常に多くのことを行いますが、それはあなたがそうすべきだという意味ではありません。

プログラマー(一般的に言えば)は、正確でルールに従うことで生活を築きます-ここに、従うのが簡単なルールがあります。それは私たちが行うことのかなり基本的なものです-私たちはlike(に依存します)特定のスコープ内の一意の識別子...

ルールに違反することは、ブラウザーがあまりに順応しているために私たちにできることです-しかし、ブラウザーが整形式で有効なHTMLを必要とすることについて厳格であるならば、それが引き起こしたであろう少しの苦痛は長い間続いていたはずです返済されました!

それで、本当にそんなに悪いのでしょうか?プログラマーとしてどのように質問すればよいでしょうか?その文明に対する犯罪(-:


補遺:

あなたはそれが悪いことのようにブラウザがあまりにも適応していると書いています

私がそうしているのは、そうです。私たちは複雑なルールについて話しているのではなく、物事を整形式にすることと、それ以外の場合は機械的にテストできるルールを適用して、結果を機械的に処理しやすくすることについて話しているからです。ブラウザーが厳格だったとしたら、ツールはそれをサポートするために非常に迅速に適応したでしょう-そうではなかったのです。考えてみてください。MSとNetscapeが制限のないHTMLを許可することで、MSとNetscapeがそれを台無しにしていない場合、引用テキストを明示的にサポートするはるかに複雑な「電子メールマークアップ言語」ではるかに優れたツールが得られるはずです。 ...しかし、その船は出航し、同様に、ブラウザーが許可する安定ドアを閉じることはできません(私たちはshould、HTML5 should have)ができません。

8
Murph

スクリプトでは:getElementByIDは最初の一致のみを返します。 CSS:#idは、そのIDを持つすべての要素に影響します。ブラウザレンダーでは何の効果もありません。

これは、w3c標準の動作です。可能ではありません。事実上定義されたものです。

https://dom.spec.whatwg.org/#interface-nonelementparentnode

7
Bart Calixto