Vários elementos HTML diferentes podem ter o mesmo ID se forem elementos diferentes?

139

Um cenário como este é válido ?:

div#foo
span#foo
a#foo
omninonsense
fonte
23
Embora às vezes seja possível, nunca é válido.
Paul Creasey
2
Com tudo dito acima, vale a pena notar que é provável que encontre vários mesmos IDs em um documento com conteúdo criado pelo agente do usuário (pense em estruturas, mv *, reagir, polímero ...). Isso é se alguém está se perguntando por que um site XYZ de aparência muito profissional está repleto de códigos de práticas inadequadas.
Lukasz Matysiak

Respostas:

180

Não.

Os IDs dos elementos devem ser exclusivos em todo o documento.

SLaks
fonte
85
Quais são as consequências de não fazer isso?
CorsiKa
16
@corsiKa a conseqüência é um comportamento indefinido, por exemplo, o que document.getElementById ("# foo") ou $ ("# foo") retornam quando há vários #foos? Você vai correr em problemas Ser capaz de trabalhar com esses elementos de JS, passá-los como seletores para bibliotecas / APIs / Flash, etc.
mrooney
76
Isto está incorreto. É inteiramente possível ter vários elementos com o mesmo ID. Geralmente, não é uma prática recomendada , mas tem usos ocasionais. Todo mundo parece citar como os seletores funcionariam, bem, se você souber que terá IDs conflitantes, use-os com um pai, onde os IDs sob o pai seriam únicos. por exemplo, $('div#car span#size)e $('div#truck span#size').
BJury
18
por que usar vários IDs semelhantes quando você obtém classe para esse fim?
Max Yari
6
Sim, vários IDs podem, na prática, ser substituídos usando classes. No entanto, as classes são destinadas a aplicar estilos, não a identificar elementos, tornando o escopo dos nomes muito mais amplo e, portanto, provável que se sobreponham. Especialmente se estiver usando bibliotecas de terceiros. O ID como 'identificador' não se destina a ser multiplicado; portanto, há claramente a necessidade de algo intermediário. O uso prático é a componenteização de seções de uma página / domínio em unidades lógicas separadas. Portanto, é necessário usar (pelo menos) identificação em duas camadas.
Alen Siljak
85

Eu acho que existe uma diferença entre se algo DEVE ser único ou DEVE ser único (ou seja, imposto pelos navegadores da web).

Os IDs devem ser exclusivos? SIM.

Os IDs devem ser exclusivos? NÃO, pelo menos o IE e o FireFox permitem que vários elementos tenham o mesmo ID.

Jin Kim
fonte
6
O mesmo acontece com o Chrome (v22 no momento em que este comentário foi escrito). : D
omninonsense
27
De acordo com as especificações , este é um DEVE, não DEVE. (Será que ela ainda funciona na maioria dos navegadores Sim Será que é HTML válido Não. Além disso, para?.? getElementById, O resultado em tais casos é undefined, o que significa que não há nenhuma maneira de dizer como um navegador pode escolheu para lidar com isso.)
leo
2
@leo, no entanto, este é o mundo real onde os navegadores não estão totalmente em conformidade com os padrões. Nesse caso, pode ser uma coisa boa, pois não há motivo para aplicar IDs exclusivos.
BJury
1
No HTML5, a especificação para getElementByIdrealmente define que o primeiro elemento com o ID fornecido deve ser retornado (que é como todos os navegadores atualmente lidam com a situação) - veja minha resposta abaixo para obter mais informações.
Mltsy 16/05/19
1
Não chore, use jQuery. @leo
Máxima Alekz
67

Vários elementos podem ter o mesmo ID?

Sim - independentemente de terem a mesma tag ou não, os navegadores renderizarão a página mesmo que vários elementos tenham o mesmo ID.

É HTML válido?

Não. Isso ainda é verdade na especificação do HTML 5.1 . No entanto, a especificação também diz que getElementById deve retornar o primeiro elemento com o ID fornecido , tornando o comportamento não indefinido no caso de um documento inválido.

Quais são as conseqüências desse tipo de HTML inválido?

A maioria (se não todos) os navegadores selecionou e ainda não selecione o primeiro elemento com um determinado ID, ao chamar getElementById. A maioria das bibliotecas que encontram elementos por ID herda esse comportamento. A maioria dos navegadores (se não todos) também aplica estilos atribuídos pelos seletores de identificação (por exemplo,#myid ) a todos os elementos com o ID especificado. Se é isso que você espera e pretende, não há consequências não intencionais. Se você espera / pretende outra coisa (por exemplo, que todos os elementos com esse ID sejam retornados ou que o estilo se aplique a apenas um elemento), suas expectativas não serão atendidas e qualquer recurso que contenha essas expectativas falhará.

Algumas bibliotecas JavaScript não tem expectativas que não são cumpridas quando vários elementos têm o mesmo ID (veja o comentário de wootscootinboogie sobre d3.js)

Conclusão

É melhor seguir os padrões, mas se você sabe que seu código funciona conforme o esperado em seus ambientes atuais e esses IDs são usados ​​de maneira previsível / sustentável, existem apenas duas razões práticas para não fazer isso:

  1. Para evitar a chance de você estar errado, e uma das bibliotecas que você usa realmente funciona mal quando vários elementos têm o mesmo ID.
  2. Para manter a compatibilidade futura do seu site / aplicativo com bibliotecas ou serviços (ou desenvolvedores!), Você poderá encontrar no futuro, que funcionará mal quando vários elementos tiverem o mesmo ID - o que é uma possibilidade razoável, já que isso não é tecnicamente válido HTML.

O poder é seu!

mltsy
fonte
Excelente resposta. é sempre melhor se você seguir os padrões.
EKanadily
25

Mesmo que os elementos sejam de tipos diferentes, isso pode causar alguns problemas sérios ...

Suponha que você tenha 3 botões com o mesmo ID:

<button id="myid" data-mydata="this is button 1">button 1</button>
<button id="myid" data-mydata="this is button 2">button 2</button>
<button id="myid" data-mydata="this is button 3">button 3</button>

Agora você configura algum jQuerycódigo para fazer algo quando os myidbotões são clicados:

$(document).ready(function ()
{
    $("#myid").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interestingFunction();

        $('form').trigger('submit');
    });
});

O que você esperaria? Que todos os botões clicados executariam a configuração do manipulador de eventos click com jQuery. Infelizmente isso não vai acontecer. SOMENTE o botão chama o manipulador de cliques. Os outros 2, quando clicados, não fazem nada. É como se não fossem botões!

Portanto, sempre atribua diferentes IDsaos HTMLelementos. Isso vai te proteger contra coisas estranhas. :)

<button id="button1" class="mybtn" data-mydata="this is button 1">button 1</button>
<button id="button2" class="mybtn" data-mydata="this is button 2">button 2</button>
<button id="button3" class="mybtn" data-mydata="this is button 3">button 3</button>

Agora, se você desejar que o manipulador de eventos click seja executado quando qualquer um dos botões for clicado, ele funcionará perfeitamente se você alterar o seletor no código jQuery para usar o CSS classe aplicada a eles assim:

$(document).ready(function ()
{
    $(".mybtn").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interstingFunction();

        $('form').trigger('submit');
    });
});
Leniel Maccaferri
fonte
e se eu tiver um "#content" que eu já referenciei em uma variável e um # my-div #content que eu tenha apenas por alguns instantes após o qual remova o nó referenciado e esqueça sua variável, após o qual o # div #content executa um myDiv.outerHTML = myDiv.innerHTML para substituir o original. Isso evita a necessidade de copiar todos os estilos e conteúdos de #content para #decoy e fazer a mesma coisa. Isso faz sentido ao fazer transições.
Dmitry
Isto significa que, mesmo se eu usar 'append' para adicionar vários elementos da mesma id, DOM única considera primeiro elemento a ser real, de preferência 1 ID = 1 Elemento
Karan Kaw
22

Não. Dois elementos com o mesmo ID não são válidos. Os IDs são únicos; se você deseja fazer algo assim, use uma classe. Não esqueça que os elementos podem ter várias classes usando um espaço como um delimitador:

<div class="myclass sexy"></div>
Gazler
fonte
12

A especificação oficial para HTML declara que as tags de identificação devem ser únicas E a especificação oficial também afirma que, se a renderização puder ser concluída, ela deve (por exemplo, não existem "erros" em HTML, apenas HTML "inválido"). Portanto, a seguir, veja como as tags de identificação realmente funcionam na prática . Eles são todos inválidos , mas ainda funcionam:

Este:

<div id="unique">One</div>
<div id="unique">Two</div>

Renderiza bem em todos os navegadores. No entanto, document.getElementById retorna apenas um objeto, não uma matriz; você só poderá selecionar a primeira div por meio de uma tag de identificação. Se você alterar o ID da primeira div usando JavaScript, o segundo ID estará acessível com document.getElementById (testado no Chrome, FireFox e IE11). Você ainda pode selecionar a div usando outros métodos de seleção, e sua propriedade id será retornada corretamente.

Observe esse problema acima abre uma vulnerabilidade de segurança em potencial em sites que renderizam imagens SVG, pois os SVGs podem conter elementos DOM e também tags de identificação neles (permite redirecionamentos de DOM do script por meio de imagens carregadas). Desde que o SVG esteja posicionado no DOM antes do elemento que ele substitui, a imagem receberá todos os eventos JavaScript destinados ao outro elemento.

No momento, esse problema não está no radar de ninguém, mas é real.

Este:

<div id="unique" id="unique-also">One</div>

Também é bom em todos os navegadores. No entanto, apenas o primeiro ID que você define dessa maneira é utilizado, se você tentou document.getElementById ('unique-also'); no exemplo acima, você retornaria nulo (testado no Chrome, FireFox e IE11).

Este:

<div id="unique unique-two">Two</div>

Também é excelente em todos os navegadores, no entanto, diferentemente das tags de classe que podem ser separadas por um espaço, a tag id permite espaços; portanto, o id do elemento acima é realmente "unique unique-two" e solicita ao dom "unique" ou "unique-two" isoladamente retorna nulo, a menos que seja definido de outra forma no DOM (testado no Chrome, FireFox e IE11).

Nick Steele
fonte
1
"a tag id permite espaços" - embora, de acordo com a especificação , o "O valor não deva conter caracteres de espaço".
precisa saber é o seguinte
Concordo. No entanto, existe a especificação e o funcionamento dos navegadores. Os navegadores historicamente tratam as especificações como algo de um objetivo, mas não são rigorosos em muitos dos itens. Eu acho que eles fazem isso porque, se atendessem às especificações, isso quebraria muitos sites existentes ou algo assim. Menciono no topo que, embora essas coisas funcionem, elas são inválidas.
Nick Steele
5

A resposta do SLaks está correta, mas como um adendo, observe que as especificações x / html especificam que todos os IDs devem ser exclusivos em um documento html (único) . Embora não seja exatamente o que o op pediu, pode haver instâncias válidas nas quais o mesmo ID é anexado a diferentes entidades em várias páginas.

Exemplo:

(veiculado para navegadores modernos) article # main-content { styled one way }
(veiculado para legado) div # main-content { estilizado de outra maneira }

Provavelmente um antipadrão embora. Apenas saindo daqui como um ponto de defesa do diabo.

RobW
fonte
1
Bom ponto. Embora o conteúdo gerado dinamicamente, que deveria ser inserido em outra página, evite os IDs completamente. Os IDs são como globais em linguagens de programação, você pode usá-los, e existem casos válidos em que é um bom truque que simplifica as coisas. É uma boa prática considerar fazer as coisas antes de fazer hacks.
Psycho brm
4

E pelo que vale a pena, pelo menos no Chrome 26.0.1410.65, Firefox 19.0.2 e Safari 6.0.3, se você tiver vários elementos com o mesmo ID, os seletores de jquery (pelo menos) retornarão o primeiro elemento com esse ID.

por exemplo

<div id="one">first text for one</div>
<div id="one">second text for one</div>

e

alert($('#one').size());

Veja http://jsfiddle.net/RuysX/ para um teste.

denishaskin
fonte
A menos que você use um seletor mais complexo, como div#oneIsso, é claro, não muda o fato de ser inválido.
Kevin B
Possivelmente, essa resposta é verdadeira, estou dizendo isso por experiência própria.
Dibyanshu Jaiswal
4

Bem, usando o validador HTML em w3.org , específico para HTML5, os IDs devem ser exclusivos

Considere o seguinte...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">Barry</div>
        <div id="x">was</div>
        <div id="x">here</div>
    </body>
</html>

o validador responde com ...

Line 9, Column 14: Duplicate ID x.      <div id="x">was</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>
Error Line 10, Column 14: Duplicate ID x.       <div id="x">here</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>

... mas o OP declarou especificamente - e os diferentes tipos de elementos. Portanto, considere o seguinte HTML ...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">barry
            <span id="x">was here</span>
        </div>
    </body>
</html>

... o resultado do validador é ...

Line 9, Column 16: Duplicate ID x.          <span id="x">was here</span>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">barry

Conclusão:

Nos dois casos (mesmo tipo de elemento ou tipo de elemento diferente), se o ID for usado mais de uma vez, não será considerado HTML5 válido.

barrypicker
fonte
2

Podemos usar o nome da classe em vez de usar o id. A identificação html deve ser única, mas as classes não. ao recuperar dados usando o nome da classe, pode reduzir o número de linhas de código nos arquivos js.

$(document).ready(function ()
{
    $(".class_name").click(function ()
    {
        //code
    });
});

Malith Ileperuma
fonte
1

Eu acho que você não pode fazer isso porque o Id é único, você precisa usá-lo para um elemento. Você pode usar a classe para esse fim

janaravi
fonte
1

<div id="one">first text for one</div>
<div id="one">second text for one</div>

var ids = document.getElementById('one');

IDs contêm apenas o primeiro elemento div. Portanto, mesmo se houver vários elementos com o mesmo ID, o objeto do documento retornará apenas a primeira correspondência.

ganesh phirke
fonte
0

Não, os IDs precisam ser únicos. Você pode usar classes para esse fim

<div class="a" /><div class="a b" /><span class="a" />

div.a {font: ...;}
/* or just: */
.a {prop: value;}
phihag
fonte
0

É possível ter mais de um aluno em uma turma com o mesmo número de rolo / ID? No idatributo HTML é assim. Você pode usar a mesma classe para eles. por exemplo:

<div class="a b c"></div>
<div class="a b c d"></div>

E assim por diante.

thecodeparadox
fonte
0

Geralmente, é melhor não usar o mesmo ID várias vezes em uma página html. Mesmo assim, é possível usar o mesmo ID várias vezes em uma página. No entanto, quando você usa um ID como parte do URI / URL, como abaixo:

https://en.wikipedia.org/wiki/FIFA_World_Cup#2015_FIFA_corruption_case

E se o ID ('2015_FIFA_corruption_case') for usado para apenas um elemento (extensão) na página da web:

<span class="mw-headline" id="2015_FIFA_corruption_case">2015 FIFA corruption case</span>

Não haveria problema. Pelo contrário, o mesmo ID existe em mais de um lugar, o navegador ficaria confuso.

Park JongBum
fonte
0

Sim eles podem.

Não sei se todas essas respostas estão desatualizadas, mas basta abrir o youtube e inspecionar o html. Tente inspecionar os vídeos sugeridos, você verá que todos eles têm o mesmo ID e estrutura repetitiva da seguinte maneira:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
O castigador
fonte