동일한 id 속성을 가진 두 개의 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">...

이것은 Google이기 때문에 실수가 아니라고 가정합니다.

그렇다면이 규칙을 위반하는 것이 얼마나 나쁜가? CSS와 DOM 선택에주의를 기울인 한 ID와 같은 클래스를 재사용하지 않는 이유는 무엇입니까? 누구나 의도적 으로이 작업을 수행합니까? 그렇다면 왜 그런가요?


102
"이것은 Google이기 때문에 실수가 아니라고 가정합니다." -> 구글은 완전하지 않습니다. 그들은 우리와 같은 실수를합니다.
Joeri Sebrechts

43
실제로 구글에있는 사람들은 다른 아이디를 생각할 수 없도록 검색을 마음에
새겼습니다

10
해당 페이지가 다른 HTML 조각으로 렌더링되어 한 조각의 한 개발자가 해당 ID를 사용하고 다른 조각의 다른 개발자와 동일한 일이 발생한다고 생각합니다.
Luciano

10
"정말 나쁜지"에 대한 모든 질문은이 점을 상기시켜줍니다. xkcd.com/292
Daniel Roseman

3
@DanielRoseman xkcd도 그것을 수행합니다 : what-if.xkcd.com/23/#question
SQB

답변:


140

사양에 UNIQUE가 표시됩니다

HTML 4.01 사양에 따르면 ID는 문서 전체에서 고유해야합니다.

HTML 5 사양 은 같은 말이지 만 다른 말로 말합니다. 그것은 ID가 그것 의 정의를 읽을 경우 기본적으로 문서 인 홈 서브 트리 에서 고유해야한다고 말한다 .

중복 방지

그러나 HTML 렌더러는 HTML 렌더링과 관련하여 매우 용서하므로 중복 ID를 허용합니다. 이것은 가능하면 모든 피해야되어야한다 엄격하게 피할 프로그래밍 자바 스크립트에서 ID에 의해 요소에 액세스 할 때. getElementById일치하는 요소가 여러 개있을 때 어떤 함수가 반환되어야 하는지 잘 모르겠습니다 . 해야 할 것 :

  • 오류를 반환?
  • 일치하는 첫 번째 요소를 반환 하시겠습니까?
  • 마지막으로 일치하는 요소를 반환 하시겠습니까?
  • 일치하는 요소 집합을 반환합니까?
  • 아무것도 반환하지 않습니까?

그러나 오늘날 브라우저가 안정적으로 작동하더라도 사양에 위배되므로 향후이 동작을 보장 할 수있는 사람은 없습니다. 따라서 동일한 문서 내에서 ID를 복제하지 않는 것이 좋습니다 .


1
@ missingno : HTML 5 사양에 대한 링크를 추가하여 동일한 내용이지만 다른 표현으로 설명합니다.
Robert Koritnik

6
DOM 스펙 에 따르면 , "둘 이상의 요소에 해당 값을 가진 ID 속성이있는 경우 반환되는 값은 정의되지 않습니다"(실제 값이 아니라 정의 된 "올바른"결과가 없음을 의미 함 undefined). 정의되지 않은 행동에 의존하는 것은 좋은 생각이 아닙니다.
lonesomeday

1
HTML5에 주목할 필요가있는 data-속성은 여러 개의 동일한 ID를 할당하려고 할 때 유용합니다. 이를 통해 공통된 하나의 공통 data-something속성을 가진 다양한 ID를 가질 수 있습니다 . 그래도, 내가 아는 모든 브라우저가 알 수없는 속성을 무시, 그래서 그들은있어 아마 전체 HTML 지원이 부족한 거의 모든 현대 틱 브라우저에서 안전합니다.
Tim Post

2
@JoachimSauer : 데이터 속성을 사용할 때 CSS 클래스를 사용할 때 사실이 아닌 키-값 쌍을 가질 수 있습니다. 이 경우 모두 부울 속성과 같습니다. 요소에는 CSS 클래스가 있거나 없습니다. CSS 클래스로 값을 원한다면 어떻게 든 CSS 클래스 이름으로 결합하고 나중에 구문 분석해야합니다. data속성 사용의 이점을 볼 수 있기를 바랍니다 . 또한 data-something="123"속성 을 단순히 참조 할 때 jQuery에서 즉시 사용할 수 있습니다 $(elem).data("something").
Robert Koritnik

1
@RobertKoritnik : 물론입니다! 나는 그 유스 케이스를 생각하지 않았다. 의 경우에 대해서만 생각했습니다 id="search".
Joachim Sauer

30

당신은 "얼마나 나쁜지"물었다. @RobertKoritnik의 (정확히 정확한) 답변을 조금이라도 살리려면 ...

해당 코드가 잘못되었습니다. 회색 음영이 올바르지 않습니다. 이 코드는 표준을 위반하므로 올바르지 않습니다. 유효성 검사를 통과하지 못할 것입니다.

즉, 현재 시장에 나와있는 브라우저는 그것에 대해 불평하거나 전혀 문제가 없습니다. 브라우저 는 이에 대해 불만을 제기 할 권리 가 있지만 현재 브라우저 의 현재 버전은 없습니다. 향후 버전에서이 코드를 잘못 처리하지 않을 수도 있습니다.

CSS 또는 자바 스크립트에서 해당 ID를 선택기로 사용하려는 행동은 추측 할 수 없으며 브라우저마다 다를 수 있습니다. 각 브라우저가 어떻게 반응하는지 확인하기 위해 연구를 수행 할 수 있다고 생각합니다. 가장 좋은 경우는 "class ="처럼 취급하고 목록을 선택하는 것입니다. (하지만 JavaScript 라이브러리를 혼동 할 수 있습니다. jQuery의 작성자 인 경우 "#"로 시작하는 선택기를 사용하는 경우 단일 객체를 가져 와서 목록이 완전히 저를 지칠 수도 있습니다.)

또한 첫 번째 또는 마지막 중 하나를 선택하거나 둘 중 하나를 선택하지 않거나 브라우저를 완전히 중단시킬 수 있습니다. 시도하지 않고 말할 방법이 없습니다.

"나쁘다"는 전적으로 특정 브라우저가 HTML 사양을 얼마나 엄격하게 구현하는지와 해당 사양을 위반했을 때 수행하는 작업에 전적으로 달려 있습니다.

편집 : 나는 단지 오늘 이것을 발견했다. 다양한 유형의 엔티티에 대한 검색 양식에서 다양한 구성 요소를 가져 와서이 사이트에 대한 큰 올인원보고 유틸리티를 생성하고 있습니다. 숨겨진 div에 원격 페이지의 검색 양식을로드하고 내 슬롯에 슬롯을 넣습니다. 적절한 엔티티 유형이 보고서의 소스로 선택된 경우 보고서 생성기. 따라서 폼의 숨겨진 버전과 보고서 생성기에 버전이 표시됩니다. 모든 경우에 제공되는 JavaScript는 ID로 요소를 참조하는데, 이제 페이지에 숨겨진 요소와 표시되는 요소가 두 개 있습니다.

jQuery 가하고있는 것처럼 보이는 것은 FIRST 하나를 선택하는 것입니다. 모든 경우에 정확히 내가 원하지 않는 것입니다.

필드를 가져 오려는 페이지 영역을 지정하기 위해 선택기를 작성 하여이 문제를 해결하고 있습니다 (예 : $ ( '# containerDiv #specificElement')). 그러나 귀하의 질문에 대한 답변이 하나 있습니다. Chrome의 jQuery는이 사양 위반에 직면했을 때 특정 방식으로 작동합니다.


... 관련 질문 : CSS 빠른 프로필의 ID 의무에 관한 stackoverflow.com/q/29295824/287948 .
피터 크라우스

3
"잘못된 회색 음영으로 오지 않습니다." 나는 이것을 많이 보았고 기술적으로 정확하지만 인생이나 프로그래밍에서 "참"이 아닌 것들 중 하나입니다. 당신은 간접적으로 당신의 대답에서 그것을 철저히 다루고 설명 할 수는 있지만 빅뱅 이론의이 장면은 내가 나를 위해 말하고 누군가를 웃게 만들어 줄 좋은 일을합니다 ... Stuart vs Sheldon youtube.com/ watch? v = F_1zoX5Ax9U
밤 올빼미

이것은 8 살짜리 대답이지만 OP 질문에 과장된 행동을하지만 반복되는 ID에 대한 브라우저의 관용적이고 위험한 행동에 대해서는 크게 불평하지 않으며 OP가 시도하는 것보다 훨씬 나쁩니다.
Erandros

20

정말 얼마나 나쁩니 까?

  1. 울게 해
  2. 유효하지 않습니다
  3. 많은 자바 스크립트 라이브러리가 예상대로 작동하지 않습니다
  4. 코드를 혼란스럽게 만듭니다.

경험에 따르면 주요 브라우저의 getElementById는 문서에서 첫 번째로 일치하는 요소를 반환합니다. 그러나 이것이 미래에 항상 그런 것은 아닙니다.

jQuery에 #foo와 같은 ID가 주어지면 getElementById를 사용하고 동작을 모방합니다. 이 문제를 해결해야하는 경우 (슬프지만) $ ( " * #foo")를 사용하면 jQuery가 getElementsByTagName을 사용하고 일치하는 모든 요소의 목록을 반환하도록 할 수 있습니다.

종종 다른 사이트에 대한 코드를 작성해야하며이 문제를 해결해야합니다. 단지 세계에서는 ID가 고유한지 확인하여 시작하기 위해 기능을 다시 디자인 할 필요가 없습니다. ID는 항상 고유해야합니다. 세상은 잔인하고 내가 울기 때문입니다.


5
이 대답은 내가 웃음을 울게했다!
A1rPun

8

당신은 할 수 있는 좋은 많은 일을 -하지만 당신이해야한다는 것을 의미하지 않습니다.

프로그래머 (일반적으로 말해서)로서 우리는 정확하고 규칙을 준수하여 삶을 구축합니다. 여기에 따르기 쉬운 규칙이 있습니다. 이는 우리가하는 일에 매우 기본적입니다. 우리는 주어진 범위 내에서 고유 한 식별자를 좋아합니다 (의존적) ...

규칙을 어기는 것은 브라우저가 너무 수용 적이기 때문에 할 수있는 일입니다. 그러나 브라우저가 제대로 구성되고 유효한 HTML을 필요로하는 것에 대해 엄격한 경우 실제로는 더 나아질 것입니다. 상환되었습니다!

정말 나쁜가요? 프로그래머로서 어떻게 요청할 수 있습니까? 문명에 대한 범죄 (-:


추가:

당신은 브라우저가 나쁜 것처럼 너무 수용되고 있다고 씁니다.

저는 복잡한 규칙에 대해 이야기하는 것이 아니라 기계적으로 테스트 할 수있는 규칙을 적용하고 결과를 기계적으로 쉽게 처리 할 수있게하는 규칙을 적용하는 것에 대해 이야기하고 있습니다. 브라우저가 엄격하다면 도구는이를 지원하도록 매우 빠르게 적응했을 것입니다. 그렇게하지 않았지만, 대신 실패를 악용하는 정도까지는 아니 었습니다. 인용 해보세요. 인용 된 텍스트를 명시 적으로 지원하는 훨씬 덜 복잡한 "이메일 마크 업 언어"가 우리에게 훨씬 더 나은 도구를 제공했을 때 MS와 Netscape가 무제한 HTML을 허용함으로써 이메일을 망쳐 놓지 않았다면 이메일은 훨씬 더 좋은 매체 였을 것입니다. ...하지만 그 배는 항해했고 마찬가지로있어야한다 ) 그러나 우리는 할 수 없습니다


당신은 브라우저가 나쁜 일처럼 너무 잘 수용되고 있다고 확신하지만, 당신은 그것을 믿지 않습니까?
KaptajnKold

4
나는 Murph를 말할 수 없지만, 그것이 정말로 나쁜 것이라고 생각합니다. 그런 다음이 수준의 용서 없이는 웹이 우리가 알고있는 것처럼 성장할 자극을 얻지 못했을 수 있습니다.
Andrea

1
@Andrea : 우리가 알듯이 인터넷은 성장하지 않았을 것입니다. 더 천천히 자랐을 것입니다. 그러나 올바른 코드가 무엇인지 아닌지에 대한 더 견고한 기초를 가지고 있었을 것입니다. 빠르지 만 느슨하게 작동 할 수 있지만 느리지 만 올바른 것을 선호합니다. 특히 우리가 단지 2 년 정도의 성장에 대해 이야기하는 것과 같지 않기 때문입니다.
Nicol Bolas

3
@Andrea 나는 그것이 거의 빠르게 성장했을 것이라고 내기했다. 도구는 단순히 문제를 다루기 위해 진화했을 것이다. 많은 경우에 도구는 마크 업 불량의 근본 원인이었습니다. 사실 사람들은 가장 적게 필요한 경향이 있습니다. "잘 형성되는"단계는 비교적 작고 테스트하고 시행하기에 충분히 쉬우 며 사람들은 큰 스트레스없이이를 수용했을 것입니다
Murph

1
브라우저가 수용하는 것은 끔찍한 일이 아닙니다. 그들이 모두 다른 방식으로 수용한다는 것은 끔찍합니다 .
Dan Ray

7

스크립팅에서 : getElementByID첫 번째 일치 항목 만 반환합니다. CSS에서 : #id해당 ID를 가진 모든 요소에 영향을 미칩니다. 브라우저 렌더에서는 아무런 영향을 미치지 않습니다.

이것이 w3c 표준의 동작입니다. 가능한 것은 아니지만 사실상 정의 된 것입니다.

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


7
이것은 가능한 행동 중 하나입니다. getElementById모든 요소 또는 null 객체를 완벽하게 반환 할 수 있습니다. CSS 효과는 모든 요소에 적용되거나 전혀 또는 전체가 될 수 있습니다. 또는 브라우저가 충돌 할 수 있습니다. 표준 밖에서, 동작은 정의되어 있지 않습니다
rds

2
표준은 이러한 상황에서 수행 할 작업을 지정하기 때문에 표준을 벗어난 것이 아닙니다. 따라서 아니요, getElementById는 어떤 요소도 반환 할 수 없습니다. 표준에 따르면 첫 번째 일치 항목을 반환한다고 명시되어 있습니다. 나는 표준 밖의 행동이 정의되어 있지 않다는 것에 동의합니다. 당신이 이해하지 못하는 것은 모든 경우가 표준의 일부라는 것입니다.
Bart Calixto

1
이 답변이 실제로 표준의 관련 부분 (또는 적어도 섹션 번호)의 인용을 참조로 포함하면 다소 더 좋습니다.
yoniLavi

2
@yoniLavi가 업데이트되었습니다.
Bart Calixto

2
감사합니다 @Bart. 당신은 절대적으로 옳습니다 :) 표준은 " ID가 elementId 인 노드의 자손 내 첫 번째 요소를 반환합니다."라고 말합니다 .
yoniLavi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.