同じid属性を持つ2つのHTML要素:どれほど悪いのでしょうか?


122

Googleマップのソースコードを参照するだけです。ヘッダーには、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を再利用してみませんか?誰かがこれを意図的に行っていますか?


102
「これはグーグルなので、間違いではないと思います。」-> Googleは間違いありません。彼らは私たちと同じように間違いを犯します。
ジョーリセブレヒト

43
実際にGoogleの人がしている検索、彼らは、他のIDの考えることはできませんので、彼らの心にボルトで固定:P
パンカジUpadhyay

10
そのページは異なるhtmlフラグメントからレンダリングされるため、あるフラグメントの1人の開発者がそのIDを使用し、他のフラグメントの他の開発者でも同じことが起こったと感じています。
ルチアーノ

10
「本当にどれだけ悪いのか」という質問全体が、このことを思い出させるだけです。xkcd.com
ダニエルローズマン

3
@DanielRoseman xkcdもそれを行います:what-if.xkcd.com/23/#question
SQB 14

回答:


140

仕様にはUNIQUEと書かれています

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

HTML 5仕様は同じことを言っていますが、言い換えれば。それはIDがホームサブツリーでユニークでなければならないと言います、私たちがそれの定義読むなら基本的にドキュメントです。

重複を避ける

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

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

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


1
@missingno:HTML 5仕様へのリンクを追加しました。これは、同じことについてですが、異なる表現で書かれています。
ロバートKoritnik

6
DOM仕様によると、「複数の要素にその値のID属性がある場合、返される値は未定義です」(実際の値ではなく、定義された「正しい」結果がないことを意味しますundefined)。未定義の動作に依存することはめったに良い考えではありません。
孤独な

1
HTML5に注目すると、このdata-属性は、複数の物に同じIDを割り当てたい場合に役立ちます。これによりdata-something、共通の1つの共通属性を持つさまざまなIDを使用できます。それでも、私が知っているすべてのブラウザーは未知の属性を無視するので、HTMLを完全にサポートしていない現代的なブラウザーのほとんどでおそらく安全です。
ティムポスト

2
@JoachimSauer:データ属性を使用する場合、CSSクラスを使用する場合には当てはまらないキーと値のペアを使用できます。その場合、それらはすべてブールプロパティのようなものです。要素にはCSSクラスがあるかどうかが含まれます。CSSクラスで値が必要な場合は、何らかの方法でそれらをCSSクラス名に結合し、後で解析する必要があります。これで、data属性を使用するメリットを確認できます。また、でdata-something="123"属性を参照するだけで、jQueryによってすぐに直接サポートされます$(elem).data("something")
ロバートKoritnik

1
@RobertKoritnik:もちろんです!私はそのユースケースを考えていませんでした。私はの場合についてだけ考えましたid="search"
ヨアヒムザウアー

30

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

そのコードは間違っています。不正確なものはグレーの色合いではありません。このコードは標準に違反しているため、正しくありません。検証チェックに失敗するため、そうする必要があります。

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

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

また、最初の1つ、場合によっては最後の1つを選択することも、どれも選択しないことも、ブラウザーを完全にクラッシュさせることもあります。それを試さずに伝える方法はありません。

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

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

jQueryが実行していると思われるのは、最初の1つを選択することです。これは、すべての場合において、私が望んでいないものです。

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


...関連する質問:CSSの高速プロファイルでのIDの義務に関するstackoverflow.com/q/29295824/287948
ピータークラウス

3
「正しくないものはグレーの色合いではありません。」私はこれをよく見ますが、それは技術的には正しいが、人生やプログラミングでは「真実」ではないものの1つです。あなたは間接的にそれをあなたの答えでかなり徹底的にカバーし、私は説明することができますが、ビッグバン理論のこのシーンは私に話させて、誰かを笑わせることを願っています... Stuart vs Sheldon youtube.com/ watch?v = F_1zoX5Ax9U

これは8年前の答えですが、OPの質問について誇張しているが、繰り返しのIDに関するブラウザの許容的で危険な動作についてあまり文句を言っていないことは非常に不均衡だと思います。これはOPがやろうとしていることよりもはるかに悪いです
エランドロス

20

それは本当にどれほど悪いですか?

  1. 泣かせる
  2. 無効です
  3. 多くのjavascriptライブラリは期待どおりに動作しません
  4. あなたのコードを混乱させます

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

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

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


5
この答えは私を泣かせた...笑い声!
A1rPun

8

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

プログラマー(一般的に言えば)として、私たちは正確で規則に従うことで生活を築きます-ここに、従うのが簡単で、それが私たちがすることのかなり基本的な規則があります-私たちは与えられた範囲内の一意の識別子が好きです...

ブラウザーがあまりにも順応性が高いため、ルールを破ることはできますが、ブラウザーが整形式で有効なHTMLの必要性に厳しい場合は、実際にはすべての方が良いでしょう。返済されました!

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


補遺:

あなたは、それは悪いことのようにブラウザがあまりにも収容されていると書いています

私はそうです-複雑なルールについて話しているのではなく、物事を適切に形成することと、機械的にテストでき、結果を機械的に処理しやすくするルールを適用することについて実質的に話している ブラウザーが厳格であれば、ツールはそれをサポートするように非常に迅速に適応していました-そうではなかったので、代わりにその失敗を悪用する程度まで。考えてみてください-引用テキストを明示的にサポートするはるかに複雑でない「電子メールマークアップ言語」がはるかに優れたツールを提供してくれたときに、MSとNetscapeが無制限のHTMLを許可することでメールを邪魔しなかったなら、電子メールははるかに優れた媒体だったでしょう...しかし、その船は航海し、同様に我々はできる)が必要ですが、できません


あなたは、それが悪いことのようにブラウザがあまりにも受け入れやすいと書いていますが、確かにあなたはそれを信じていませんか?
KaptajnKold

4
私はマーフの代弁をすることはできませんが、確かにそれは本当に悪いことだと思います。繰り返しますが、このレベルの許しがなければ、ウェブは私たちが知っているように成長する衝動を持っていなかったかもしれません。
アンドレア

1
@アンドレア:私たちが知っているように、インターネットは成長しなかっただろう。もっとゆっくり成長していたでしょう。しかし、それはまた、正しいコードとそうでないコードのより強固な基盤を持っていたでしょう。速いが、ずさんな動作をするかもしれませんが、私は、遅いが正しい動作を好みます。特に、数年の成長程度について話しているだけではないので。
ニコルボーラス

3
@Andrea私は、それがほぼ同じくらい急速に成長するだろうと確信しています-ツールは単に問題に対処するために進化したでしょう。多くの場合、ツールは貧弱なマークアップの根本原因でした。実際には、人々が最も必要な操作を行う傾向があることである- 「整形」するステップは、比較的小さなものとするためにテストし、施行するのは簡単で、人々は大きなストレスなくことを収容しているだろう
Murph

1
ブラウザが対応しているのは恐ろしいことではありません。彼らがすべて異なる方法で収容ているのは恐ろしいです。
ダン・レイ

7

In Scripting:getElementByID最初の一致のみを返します。CSSの場合:#idそのIDを持つすべての要素に影響します。ブラウザでは、レンダリングは効果がありません。

これはw3c標準の動作です。可能性のあるものではなく、事実上定義されたものです。

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


7
これは1つの可能な動作です。getElementByIdすべての要素、またはnullオブジェクトを完全に返すことができます。CSS効果は、任意の要素に適用することも、要素をまったく適用しないことも、すべてに適用することもできます。または、ブラウザがクラッシュする可能性があります。標準のうち、動作はされ未定義
RDS

2
これらの状況では何をすべきかを規格が規定しているため、規格外ではありません。いいえ、getElementByIdは要素を返すことができませんでした。標準では、iが最初の一致を返すことを明示的に示しています。標準からの振る舞いは未定義であることに同意します。あなたが理解していないのは、これらのすべてのケースが標準の一部であるということです。
バートカリックス14

1
この回答は、参照として、標準の関連部分(または少なくともセクション番号)の引用を実際に含めた場合、いくらか改善されます。
yoniLavi

2
@yoniLaviが更新されました。
バートカリックス

2
@Bartに感謝します。あなたは絶対に正しいです:)標準では、「IDがelementIdであるノードの子孫内の最初の要素を返します」と書かれています。
yoniLavi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.