Dois elementos HTML com o mesmo atributo id: Quão ruim é realmente?

111

Apenas navegando no código-fonte do Google Maps. Em seu cabeçalho, eles têm 2 divs com id="search", um contém o outro e também tem o atributo jstrack="1". Há um formulário que os separa assim:

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

Como este é o google, estou assumindo que não é um erro.

Então, quão ruim pode ser realmente violar essa regra? Contanto que você seja cuidadoso em sua seleção de css e dom, por que não reutilizar id como classes? Alguém faz isso de propósito e, em caso afirmativo, por quê?

    
por danludwig 27.12.2011 / 18:23
fonte

5 respostas

133

Especificação diz UNIQUE

especificação HTML 4.01 diz que o ID deve ser único em todo o documento.

A especificação HTML 5 diz a mesma coisa, mas em outras palavras. Ele diz que o ID deve ser único em sua subárvore inicial , que é basicamente o documento se leia a definição dele .

Evitar duplicação

Mas, como os renderizadores de HTML são muito tolerantes quando se trata de renderização de HTML, eles permitem IDs duplicados. Isso deve ser evitado se for possível e estritamente evitado quando acessar programaticamente os elementos por IDs em JavaScript. Não tenho certeza de qual função getElementById deve retornar quando vários elementos correspondentes forem encontrados? Deveria:

  • retorna um erro?
  • retorna o primeiro elemento correspondente?
  • retorna o último elemento correspondente?
  • retorna um conjunto de elementos correspondentes?
  • não retorna nada?

Mas mesmo que os navegadores funcionem de maneira confiável atualmente, ninguém pode garantir esse comportamento no futuro, já que isso é contra a especificação. É por isso que eu recomendo que você nunca duplique IDs dentro do mesmo documento.

    
por 27.12.2011 / 18:29
fonte
29

Você perguntou "quão ruim". Então, para dar uma resposta @ RobertKoritnik (totalmente precisa) um pouco ...

Esse código está incorreto. Incorreto não vem em tons de cinza. Este código viola o padrão e, portanto, está incorreto. Isso falharia na verificação de validação e deveria.

Dito isto, nenhum navegador atualmente no mercado iria reclamar sobre isso, ou ter qualquer problema com isso. Os navegadores estariam dentro de seus direitos para reclamar sobre isso, mas nenhuma das versões atuais de qualquer deles faz atualmente. O que não significa que as futuras versões possam não tratar bem este código.

Seu comportamento ao tentar usar esse ID como seletor, seja em css ou javascript, é imprevisível e provavelmente varia de navegador para navegador. Suponho que um estudo poderia ser feito para ver como cada navegador reage a isso. Eu acho que no melhor dos casos, trataria isso como "class=" e selecionaria a lista deles. (Isso pode confundir bibliotecas JavaScript, no entanto - se eu fosse o autor do jQuery, eu poderia ter otimizado meu código seletor para que, se você vir a mim com um seletor começando com "#", eu espere um único objeto e obter um lista pode bork-me completamente.)

Ele também pode selecionar o primeiro, ou possivelmente o último, ou não selecionar nenhum deles ou bloquear totalmente o navegador. Não há como saber sem tentar.

"Quão ruim", então, depende inteiramente de quão estritamente um determinado navegador implementa a especificação HTML, e o que ela faz quando confrontada com uma violação dessa especificação.

EDIT: Acabei de me deparar com isso hoje. Eu estou puxando em vários componentes de formulários de pesquisa em vários tipos de entidades para produzir um grande e completo utilitário de relatórios para este site, estou carregando formulários de busca de páginas remotas em divs escondidos e colocando-os no meu Gerador de relatório quando o tipo de entidade apropriado é selecionado como a origem do relatório. Portanto, há uma versão oculta do formulário e uma versão exibida no gerador de relatórios. O JavaScript que veio com, em todos os casos, refere-se aos elementos por ID, dos quais existem agora TWO na página - o oculto e o exibido.

O que o jQuery parece estar fazendo é me selecionar o PRIMEIRO, que em todos os casos é exatamente o que eu NÃO QUERO.

Estou trabalhando em torno disso escrevendo seletores para especificar a região da página na qual eu quero colocar meu campo (por exemplo: $ ('# containerDiv #specificElement')). Mas há uma resposta para sua pergunta: o jQuery no Chrome definitivamente se comporta de maneira particular quando confrontado com essa violação de especificações.

    
por 27.12.2011 / 19:18
fonte
20

Quão ruim é realmente isso?

  1. Isso me faz chorar
  2. é inválido
  3. Muitas bibliotecas javascript não funcionarão conforme o esperado
  4. Isso torna o seu código confuso

A experiência diz que getElementById nos principais navegadores retornará o primeiro elemento correspondente no documento. Mas isso pode nem sempre ser o caso no futuro.

Quando jQuery recebe um id, por exemplo, #foo, ele usa getElementById e imita esse comportamento. Se você tiver que contornar isso (isso é triste), você pode usar $ (" * #foo") que convencerá o jQuery a usar getElementsByTagName e retornará uma lista de todos os elementos correspondentes.

Muitas vezes tenho que escrever código para outros sites, e tenho que contornar isso. Em um mundo justo, eu não teria que redesenhar funções para começar verificando se um ID é único. Os IDs devem ser sempre exclusivos. O mundo é cruel e é por isso que eu choro.

    
por 04.09.2012 / 11:27
fonte
8

Você pode fazer muitas coisas, mas isso não significa que você deva.

Como programador (de um modo geral), construímos nossas vidas sendo precisos e seguindo as regras - aqui está uma regra simples de seguir, que é bastante fundamental para o que fazemos - gostamos (depende de) identificadores exclusivos dentro de um dado escopo ...

Quebrar a regra é algo que podemos fazer porque o navegador é muito flexível - mas, na verdade, todos estaríamos melhor se os navegadores fossem rigorosos quanto à necessidade de HTML bem formado e válido, a pequena quantidade de dor que causaria seria já foram reembolsados há muito tempo!

Então, é tão ruim assim? Como programador, como você pode perguntar? É um crime contra a civilização (-:

Adendo:

You write that browsers are too accommodating like it's bad thing

Eu faço, porque é - não estamos falando de regras complicadas, estamos falando substancialmente sobre fazer as coisas bem formadas e aplicar regras que podem ser testadas mecanicamente e que, por sua vez, tornam mais fácil para o resultado ser processado mecanicamente. Se os navegadores tivessem sido rigorosos, as ferramentas se adaptariam muito rapidamente para suportar isso - não foi o que não fizeram, algumas até o ponto de explorarem a falha. Basta pensar sobre isso - o e-mail teria sido uma mídia muito mais agradável se a MS e a Netscape não tivessem estragado tudo permitindo HTML irrestrito quando uma "linguagem de marcação de e-mail" muito menos complexa com suporte explícito para texto citado teria nos dado uma ferramenta muito melhor ... mas esse navio navegou e da mesma forma não podemos fechar a porta do estábulo no que os navegadores permitem (nós devemos , HTML5 deve ter ) mas não podemos

    
por 27.12.2011 / 21:47
fonte
5

Em Scripting: getElementByID retornará apenas a primeira correspondência. Em CSS: #id afetará TODOS os elementos com esse ID. No Browser Render não terá qualquer efeito.

Este é o comportamento do padrão w3c. Não é possível, é o facto definido.

link

    
por 27.12.2011 / 22:35
fonte