Plusieurs éléments HTML différents peuvent-ils avoir le même ID s’ils sont différents?

139

Un scénario comme celui-ci est-il valide?:

div#foo
span#foo
a#foo
omninonsense
la source
23
Bien que parfois possible, ce n'est jamais valide.
Paul Creasey
2
Compte tenu de tout ce qui précède, il convient de noter qu'il est susceptible de rencontrer plusieurs identifiants identiques dans un document avec un contenu créé par un agent utilisateur (think frameworks, mv *, react, polymère ...). C'est si quelqu'un se demandait pourquoi un site XYZ d'aspect très professionnel regorge de codes de mauvaise pratique .
Lukasz Matysiak

Réponses:

180

Non.

Les ID d'élément doivent être uniques dans tout le document.

SLaks
la source
85
Quelles sont les conséquences de ne pas le faire?
corsiKa
16
@corsiKa la conséquence est un comportement indéfini, par exemple, que renvoie document.getElementById ("# foo") ou $ ("# foo") quand il y a plusieurs #foos? Vous rencontrerez des problèmes pour pouvoir travailler avec ces éléments depuis JS, les transmettre comme sélecteurs aux bibliothèques / API / Flash, etc.
mrooney
76
Ceci est une erreur. Il est tout à fait possible d'avoir plusieurs éléments avec le même identifiant. Ce n'est généralement pas la meilleure pratique , mais il a ses utilisations occasionnelles. Tout le monde semble citer comment les sélecteurs fonctionneraient, eh bien, si vous savez que vous avez des identifiants en conflit, vous utilisez vos sélecteurs avec un parent, où les identifiants sous le parent seraient uniques. par exemple $('div#car span#size)et $('div#truck span#size').
BJury
18
pourquoi même utiliser plusieurs identifiants similaires lorsque vous avez une classe à cet effet?
Max Yari
6
Oui, plusieurs identifiants peuvent, en pratique, être remplacés en utilisant des classes. Cependant, les classes sont destinées à appliquer des styles et non à identifier des éléments, ce qui élargit considérablement la portée des noms et donc risque de se chevaucher. Surtout si vous utilisez des bibliothèques tierces. L'identifiant comme «identifiant» n'est pas destiné à être multiplié, il y a donc clairement un besoin de quelque chose entre les deux. L'utilisation pratique est la mise en composants de sections d'une page / dom en unités logiques séparées. L'utilisation (au moins) d'une identification à 2 couches est donc nécessaire.
Alen Siljak
85

Je pense qu'il y a une différence entre si quelque chose DEVRAIT être unique ou DOIT être unique (c'est-à-dire imposé par les navigateurs Web).

Les identifiants doivent-ils être uniques? OUI.

Les identifiants doivent-ils être uniques? NON, au moins IE et FireFox permettent à plusieurs éléments d'avoir le même ID.

Jin Kim
la source
6
Il en va de même pour Chrome (v22 au moment de la rédaction de ce commentaire). : D
omninonsense
27
Selon la spécification , c'est un MUST, pas un DEVRAIT. (Est-ce que cela fonctionne toujours dans la plupart des navigateurs? Oui. Est-ce du HTML valide? Non. De plus, getElementByIdle résultat dans de tels cas est undefinedqu'il n'y a aucun moyen de dire comment un navigateur pourrait choisir de le gérer.)
leo
2
@leo cependant c'est le monde réel où les navigateurs ne sont pas entièrement conformes aux normes. Dans ce cas, cela pourrait être une bonne chose, car il n'y a aucune raison d'appliquer des identifiants uniques.
BJury
1
En HTML5, la spécification de getElementByIddéfinit en fait que le premier élément avec l'ID donné doit être retourné (c'est ainsi que tous les navigateurs gèrent actuellement la situation de toute façon) - voir ma réponse ci-dessous pour en savoir plus.
mltsy
1
Ne pleure pas, utilise jQuery. @leo
Máxima Alekz
67

Plusieurs éléments peuvent-ils avoir le même identifiant?

Oui - qu'il s'agisse de la même balise ou non, les navigateurs afficheront la page même si plusieurs éléments ont le même identifiant.

Est-ce du HTML valide?

Non. Cela est toujours vrai à partir de la spécification HTML 5.1 . Cependant, la spécification indique également qu'il getElementById faut retourner le premier élément avec l'ID donné , ce qui rend le comportement non indéfini dans le cas d'un document invalide.

Quelles sont les conséquences de ce type de HTML invalide?

La plupart (sinon tous) les navigateurs ont sélectionné et encore ne sélectionnez le premier élément avec un identifiant donné, lors de l' appel getElementById. La plupart des bibliothèques qui trouvent des éléments par ID héritent de ce comportement. La plupart des navigateurs (sinon tous) appliquent également des styles attribués par des sélecteurs d'ID (par exemple #myid) à tous les éléments avec l'ID spécifié. Si c'est ce que vous attendez et avez l'intention, alors il n'y a pas de conséquences involontaires. Si vous attendez / avez l'intention de quelque chose d'autre (par exemple pour que tous les éléments avec cet ID soient retournés, ou pour que le style s'applique à un seul élément) alors vos attentes ne seront pas satisfaites et toute fonctionnalité reposant sur ces attentes échouera.

Certaines bibliothèques javascript n'ont des attentes qui ne sont pas remplies lorsque plusieurs éléments ont le même ID (voir le commentaire de wootscootinboogie à propos d3.js)

Conclusion

Il est préférable de respecter les normes, mais si vous savez que votre code fonctionne comme prévu dans vos environnements actuels, et que ces identifiants sont utilisés de manière prévisible / maintenable, il n'y a que 2 raisons pratiques de ne pas le faire:

  1. Pour éviter le risque que vous vous trompiez et que l'une des bibliothèques que vous utilisez fonctionne mal lorsque plusieurs éléments ont le même ID.
  2. Pour maintenir la compatibilité ascendante de votre site Web / application avec les bibliothèques ou services (ou développeurs!) Que vous pourriez rencontrer à l'avenir, qui fonctionnent mal lorsque plusieurs éléments ont le même ID - ce qui est une possibilité raisonnable car ce n'est pas, techniquement, valide HTML.

Le pouvoir est à vous!

mltsy
la source
Excellente réponse. il est toujours préférable de respecter les normes.
EKanadily
25

Même si les éléments sont de types différents cela peut vous causer de sérieux problèmes ...

Supposons que vous ayez 3 boutons avec le même identifiant:

<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>

Maintenant, vous configurez du jQuerycode pour faire quelque chose lorsque vous myidcliquez sur les boutons:

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

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

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

A quoi vous attendriez-vous? Que chaque bouton cliqué exécute la configuration du gestionnaire d'événements click avec jQuery. Malheureusement, cela n'arrivera pas. SEULEMENT le 1er bouton appelle le gestionnaire de clics. Les 2 autres lorsque vous cliquez dessus ne font rien. C'est comme si ce n'étaient pas du tout des boutons!

Donc , toujours affecter différents IDsà des HTMLéléments. Cela vous protégera contre des choses étranges. :)

<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>

Maintenant, si vous voulez que le gestionnaire d'événement de clic s'exécute lorsque l'un des boutons est cliqué, cela fonctionnera parfaitement si vous modifiez le sélecteur dans le code jQuery pour utiliser la CSSclasse qui leur est appliquée comme ceci:

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

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

        $('form').trigger('submit');
    });
});
Leniel Maccaferri
la source
que se passe-t-il si j'ai un "#content" que j'ai déjà référencé dans une variable, et un # my-div #content que je n'ai que quelques instants après quoi je supprime le nœud référencé et oublie sa variable, après quoi le # div #content exécute un myDiv.outerHTML = myDiv.innerHTML pour remplacer l'original. Cela évite d'avoir à copier sur papier tous les styles et contenus de #content dans #decoy et de faire la même chose. Cela a du sens lors des transitions.
Dmitry
Cela signifie que, même si j'utilise 'append' pour ajouter plusieurs éléments du même identifiant, DOM considère uniquement le premier élément comme réel, idéalement 1 ID = 1 élément
Karan Kaw
22

Non, deux éléments avec le même identifiant ne sont pas valides. Les identifiants sont uniques, si vous souhaitez faire quelque chose comme ça, utilisez une classe. N'oubliez pas que les éléments peuvent avoir plusieurs classes en utilisant un espace comme délimiteur:

<div class="myclass sexy"></div>
Gazler
la source
12

La spécification officielle pour HTML stipule que les balises id doivent être uniques ET la spécification officielle stipule également que si le rendu peut être terminé, il le doit (c'est-à-dire qu'il n'y a pas d '"erreurs" dans HTML, seulement du HTML "invalide"). Voici donc comment les balises d'identification fonctionnent réellement dans la pratique . Ils sont tous invalides , mais fonctionnent toujours:

Ce:

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

Rend bien dans tous les navigateurs. Cependant, document.getElementById ne renvoie qu'un objet, pas un tableau; vous ne pourrez sélectionner le premier div que via un identifiant. Si vous deviez changer l'id du premier div en utilisant JavaScript, le second ID serait alors accessible avec document.getElementById (testé sur Chrome, FireFox & IE11). Vous pouvez toujours sélectionner le div en utilisant d'autres méthodes de sélection, et sa propriété id sera renvoyée correctement.

Veuillez noter que ce problème ci-dessus ouvre une faille de sécurité potentielle dans les sites qui rendent des images SVG, car les SVG sont autorisés à contenir des éléments DOM, ainsi que des balises d'identification sur eux (permet les redirections DOM de script via des images téléchargées). Tant que le SVG est positionné dans le DOM avant l'élément qu'il remplace, l'image recevra tous les événements JavaScript destinés à l'autre élément.

Ce problème n'est actuellement sur le radar de personne pour autant que je sache, mais il est réel.

Ce:

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

Rend également très bien dans tous les navigateurs. Cependant, seul le premier identifiant que vous définissez de cette manière est utilisé, si vous avez essayé document.getElementById ('unique-also'); dans l'exemple ci-dessus, vous serez renvoyé null (testé sur Chrome, FireFox et IE11).

Ce:

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

Le rendu est également correct dans tous les navigateurs, cependant, contrairement aux balises de classe qui peuvent être séparées par un espace, la balise id autorise les espaces, donc l'id de l'élément ci-dessus est en fait "unique unique-two", et demande au dom "unique" ou "unique-deux" dans l'isolement renvoie null, sauf indication contraire ailleurs dans le DOM (testé sur Chrome, FireFox et IE11).

Nick Steele
la source
1
"La balise id autorise les espaces" - Bien que, selon la spécification , le "La valeur ne doit pas contenir de caractères d'espacement."
MrWhite
Je suis d'accord. Cependant, il y a les spécifications, et il y a comment les navigateurs fonctionnent. Les navigateurs traitent historiquement la spécification comme un objectif, mais n'ont pas été stricts sur de nombreux éléments. Je pense qu'ils font cela parce que s'ils respectaient les spécifications, cela casserait beaucoup de sites existants ou quelque chose du genre. Je mentionne en haut que bien que ces choses fonctionnent, elles sont invalides.
Nick Steele
5

La réponse de SLaks est correcte, mais comme un addendum note que les spécifications x / html spécifient que tous les identifiants doivent être uniques dans un (unique) document html . Bien que ce ne soit pas exactement ce que l'op a demandé, il pourrait y avoir des instances valides où le même identifiant est attaché à différentes entités sur plusieurs pages.

Exemple:

(servi aux navigateurs modernes) article # main-content { styled one way }
(servi à l'ancien) div # main-content { styled another way }

Probablement un anti-modèle cependant. Je laisse juste ici comme un point d'avocat du diable.

RobW
la source
1
Bon point. Bien que le contenu généré dynamiquement qui est censé être inséré dans une autre page devrait éviter complètement les identifiants. Les identifiants sont comme des globaux dans les langages de programmation, vous pouvez les utiliser, et il existe des cas valides où c'est un bon hack qui simplifie les choses. C'est une bonne pratique d'envisager de faire les choses correctement avant de faire des hacks.
psycho brm
4

Et pour ce que ça vaut, sur Chrome 26.0.1410.65, Firefox 19.0.2 et Safari 6.0.3 au moins, si vous avez plusieurs éléments avec le même ID, les sélecteurs jquery (au moins) renverront le premier élément avec cet ID.

par exemple

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

et

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

Voir http://jsfiddle.net/RuysX/ pour un test.

denishaskin
la source
À moins que vous n'utilisiez un sélecteur plus complexe, tel que div#onecela, bien sûr, cela ne change pas le fait qu'il est invalide.
Kevin B
Cette réponse est peut-être vraie, je le dis par expérience.
Dibyanshu Jaiswal
4

Eh bien, en utilisant le validateur HTML sur w3.org , spécifique à HTML5, les identifiants doivent être uniques

Considérer ce qui suit...

<!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>

le validateur répond par ...

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>

... mais le PO a spécifiquement déclaré - qu'en est-il des différents types d'éléments. Considérez donc le HTML suivant ...

<!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>

... le résultat du validateur est ...

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

Conclusion:

Dans les deux cas (même type d'élément ou type d'élément différent), si l'id est utilisé plus d'une fois, il n'est pas considéré comme du HTML5 valide.

barrypicker
la source
2

Nous pouvons utiliser le nom de la classe au lieu d'utiliser id. Les identifiants html doivent être uniques, mais les classes ne le sont pas. lors de la récupération de données en utilisant le nom de classe peut réduire le nombre de lignes de code dans vos fichiers js.

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

Malith Ileperuma
la source
1

Je pense que vous ne pouvez pas le faire parce que l'Id est unique, vous devez l'utiliser pour un élément. Vous pouvez utiliser la classe dans ce but

janaravi
la source
1

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

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

Les ids contiennent uniquement le premier élément div. Ainsi, même s'il y a plusieurs éléments avec le même identifiant, l'objet document ne retournera que la première correspondance.

Ganesh Phirke
la source
0

Non, les identifiants doivent être uniques. Vous pouvez utiliser des classes à cet effet

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

div.a {font: ...;}
/* or just: */
.a {prop: value;}
Phihag
la source
0

Est-il possible d'avoir plus d'un élève dans une classe ayant le même numéro de rôle / ID? Dans l' idattribut HTML est comme ça. Vous pouvez utiliser la même classe pour eux. par exemple:

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

Etc.

thecodeparadox
la source
0

Habituellement, il est préférable de ne pas utiliser le même identifiant plusieurs fois dans une page html. Même ainsi, il est possible d'utiliser le même identifiant plusieurs fois dans une page. Cependant, lorsque vous utilisez un ID dans le cadre de l'URI / URL comme ci-dessous:

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

Et si l'ID ('2015_FIFA_corruption_case') est utilisé pour un seul élément (span) dans la page Web:

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

Il n'y aurait aucun problème. Au contraire, le même identifiant existe à plusieurs endroits, le navigateur serait confus.

Parc JongBum
la source
0

Oui, ils peuvent.

Je ne sais pas si toutes ces réponses sont obsolètes, mais ouvrez simplement YouTube et inspectez le html. Essayez d'inspecter les vidéos suggérées, vous verrez qu'elles ont toutes le même identifiant et la même structure répétitive comme suit:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
ThePunisher
la source