Due elementi HTML con lo stesso attributo id: quanto è grave?

111

Basta sfogliare il codice sorgente di google maps. Nella loro intestazione, hanno 2 div con id="search" uno contiene l'altro, e ha anche l'attributo jstrack="1". C'è un modulo che li separa in questo modo:

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

Poiché questo è google, presumo che non sia un errore.

Quindi quanto può essere pericoloso violare questa regola? Fintanto che stai attento nella selezione di css e dom, perché non riusare le classi come id? Qualcuno lo fa apposta, e se sì, perché?

    
posta danludwig 27.12.2011 - 18:23
fonte

5 risposte

133

La specifica dice UNIQUE

Specifiche HTML 4.01 dice che l'ID deve essere univoco per tutto il documento.

La specifica HTML 5 dice la stessa cosa, ma in altre parole. Dice che l'ID deve essere unico nella sua sottotree di casa , che è fondamentalmente il documento se noi leggi la definizione di esso .

Evita la duplicazione

Ma dal momento che i renderer HTML perdonano molto quando si tratta di rendering HTML, consentono l'uso di ID duplicati. Questo dovrebbe essere evitato se possibile e rigorosamente evitato quando si accede a livello di codice da elementi in JavaScript. Non sono sicuro di quale funzione getElementById debba restituire quando vengono trovati più elementi corrispondenti? Dovrebbe:

  • restituisce un errore?
  • restituisce il primo elemento di corrispondenza?
  • restituisce l'ultimo elemento corrispondente?
  • restituisce un insieme di elementi corrispondenti?
  • non restituire nulla?

Ma anche se i browser funzionano in modo affidabile in questi giorni, nessuno può garantire questo comportamento in futuro poiché questo è contrario alle specifiche. Ecco perché ti raccomando non duplicare mai gli ID all'interno dello stesso documento.

    
risposta data 27.12.2011 - 18:29
fonte
29

Hai chiesto "quanto male". Quindi, per dare un tocco di pietà alla risposta di RobertKoritnik (del tutto accurata) ...

Quel codice non è corretto. Non corretto non viene in sfumature di grigio. Questo codice viola lo standard ed è quindi errato. Fallirebbe il controllo della validazione, e dovrebbe.

Detto questo, nessun browser attualmente sul mercato si lamenterebbe di questo, o avrebbe avuto alcun problema con esso. I browser sarebbero nei loro diritti lamentarsi di ciò, ma nessuna delle versioni correnti di nessuno di essi attualmente lo fa. Ciò non significa che le versioni future potrebbero non trattare male questo codice.

Il tuo comportamento nel provare a utilizzare quell'ID come selettore, sia in css che in javascript, non è percettibile e probabilmente varia da browser a browser. Suppongo che si possa fare uno studio per vedere come reagisce ogni browser. Penso che nel migliore dei casi lo tratterebbe proprio come "class=", e selezioneremo la lista. (Ciò potrebbe confondere le librerie JavaScript, anche se - se fossi l'autore di jQuery, avrei potuto ottimizzare il mio codice di selezione in modo che se vieni da me con un selettore che inizia con "#", mi aspetto un singolo oggetto e ottengo un la lista potrebbe bloccarmi completamente.)

Potrebbe anche selezionare il primo, o forse l'ultimo, o selezionare nessuno di essi, o bloccare completamente il browser. Non c'è modo di dirlo senza provarlo.

"Quanto male" dipende interamente da quanto rigorosamente un particolare browser implementa le specifiche HTML e da ciò che fa quando si confronta con una violazione di tale specifica.

EDIT: mi è appena capitato di imbattermi oggi. Sto inserendo vari componenti dai moduli di ricerca su vari tipi di entità per produrre una grande utility di reporting all-in-one per questo sito, sto caricando i moduli di ricerca delle pagine remote in div nascoste e inserendole nel mio Generatore di report quando il tipo di entità appropriato è selezionato come origine per il report. Quindi c'è una versione nascosta del modulo e una versione visualizzata nel generatore di report. Il codice JavaScript fornito, in tutti i casi, fa riferimento a elementi per ID, di cui ci sono ora DUE sulla pagina, quella nascosta e quella visualizzata.

Ciò che sembra fare jQuery è selezionarmi il PRIMO, che in tutti i casi è esattamente quello che NON VOGLIO.

Ci sto lavorando attorno scrivendo i selettori per specificare la regione della pagina in cui voglio inserire il mio campo (es: $ ('# containerDiv #specificElement')). Ma c'è una risposta alla tua domanda: jQuery su Chrome si comporta in modo particolare in caso di violazione di questa specifica.

    
risposta data 27.12.2011 - 19:18
fonte
20

Quanto è grave?

  1. Mi fa piangere
  2. Non è valido
  3. Molte librerie javascript non funzioneranno come previsto
  4. Rende il tuo codice confuso

L'esperienza dice che getElementById nei principali browser restituirà il primo elemento con corrispondenza nel documento. Ma questo potrebbe non essere sempre il caso in futuro.

Quando jQuery riceve un ID es. #foo, usa getElementById e imita tale comportamento. Se devi aggirare questo problema (è triste), puoi usare $ (" * #foo") che convincerà jQuery a utilizzare getElementsByTagName e restituirà un elenco di tutti gli elementi corrispondenti.

Spesso devo scrivere codice per altri siti, e devo ovviare a questo. In un mondo giusto, non dovrei ridisegnare le funzioni per iniziare controllando se un ID è unico. Gli ID dovrebbero sempre essere unici. Il mondo è crudele e per questo piango.

    
risposta data 04.09.2012 - 11:27
fonte
8

Tu puoi fare moltissime cose - ma questo non significa che dovresti.

Come programmatori (in generale) costruiamo le nostre vite per essere precisi e seguire le regole - ecco una regola che è semplice da seguire, che è abbastanza fondamentale per quello che facciamo - ci come (dipende da) identificatori univoci all'interno di un determinato ambito ...

Rompere la regola è qualcosa che possiamo fare perché il browser è troppo accomodante - ma in realtà staremmo tutti meglio se i browser fossero severi riguardo alla necessità di avere un HTML ben formato e valido, la piccola quantità di dolore che avrebbe causato sarebbe stata sono stati da lungo tempo ripagati!

Quindi, è davvero così brutto? Come programmatore, come puoi anche chiedere? È un crimine contro la civiltà (-:

Addendum:

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

Sì, perché lo è - non stiamo parlando di regole complicate, stiamo parlando sostanzialmente di fare cose ben formate e di applicare regole che possono essere testate meccanicamente e che a loro volta rendono più facile il risultato elaborato meccanicamente. Se i browser fossero stati rigidi, gli strumenti si sarebbero adattati molto rapidamente a tale scopo, non è così che non lo erano, alcuni nella misura in cui sfruttano il fallimento. Basti pensare che l'e-mail sarebbe stata un mezzo molto più carino se MS e Netscape non l'avessero svuotato permettendo un HTML senza restrizioni quando un "linguaggio di marcatura e-mail" molto meno complesso con supporto esplicito per il testo citato ci avrebbe fornito uno strumento di gran lunga migliore ... ma quella nave ha navigato e allo stesso modo non possiamo chiudere la porta della stalla su ciò che i browser permettono (noi dovremmo , HTML5 dovrebbe avere ) ma non possiamo p>     

risposta data 27.12.2011 - 21:47
fonte
5

In Scripting: getElementByID restituirà solo la prima corrispondenza. In CSS: #id influenzerà TUTTI gli elementi con quell'ID. In Browser Render non avrà alcun effetto.

Questo è il comportamento dello standard w3c. Non è possibile, è definito come facto.

link

    
risposta data 27.12.2011 - 22:35
fonte

Leggi altre domande sui tag