Newsgroup: it.comp.lang.javascript
Titolo: document.getElement(S)ByID()

Cosa succede quando eseguo document.getElementById("divgenerico") e 
nella pagina ci sono due o piï¿œ elementi con lo stesso id?
Mi viene restituito il primo? C'ï¿œ un modo per accedere al secondo e in 
generale ai successivi? Grazie.

 generale ai successivi? Grazie.
 
Dato che non è ammesso, ogni browser decide autonomamente cosa fare.


 
"A *unique* identifier for the element.
There must *not* be multiple elements in a document that have the same
id value."
 

 id value."
 
Forse dovrei fare sempre una premessa ai miei messaggi. Non ho 
l'intenzione di costruire un'applicazione JS su mie pagine, ma di 
scrivere per hobby piccoli pezzi di codice (potrei chiamarli 
pomposamente "widget per la produttività personale" ma sarebbe davvero 
eccessivo) che devono girare su pagine altrui.
 
Infatti non ho scritto: "se nella pagina inserisco due o più elementi 
con lo stesso id?" ma piuttosto "se nella pagina ci sono due o più 
elementi con lo stesso id?".
 
So che è una cosa da non fare. Ma mi pare che i browser siano abbastanza 
"flessibili" da accettare anche html che viola le più regole elemantari. 
Le specifiche indicano, ovviamente, che tutti i tag aperti vanno chiusi. 
Eppure ci sono milioni di pagine scritte male, dove si è perso per 
strada qualche </span> o qualche </div>, che continuano a essere 
visualizzate senza problemi o con problemi minimali.
 
In questo specifico caso mi devo confrontare con una pagina che dovrebbe 
avere un div con un nome specifico. Ma non so se l'autore ha fatto le 
cose per bene, e quindi devo prendere in considerazione anche l'ipotesi 
che ci siano due div con lo stesso nome.
 
Qui comunque 
http://stackoverflow.com/questions/3607291/javascript-and-getelementbyid-for-multiple-elements-with-the-same-id
 
viene detto che
 
function getElementsById(id) {
   return [document.getElementById(id)];
}
 
restituisce la matrice degli elemtni con uno stesso nome specificato.
 

 restituisce la matrice degli elemtni con uno stesso nome specificato.
 
Dice anche:
 
calling GetElementByID automatically returns an array when there are 
multiple elements with the same ID in IE, Chrome, Safari and Opera BUT 
not FireFox
 
Semplicemente, come dice Cristiano Larghi, non è deterministico. Oggi 
funziona (tranne che con Firefox, pare). Domani non si sa.
 
Bye.

> }
 
Per r61:
 
Onestamente non vedo come questo codice possa funzionare. Ammesso che un
browser restituisca una collection con `document.getElementById`, in
questo caso hai un array con un unico elemento – una collection – che
non è ciò che vuoi ottenere.
 
Inoltre se ho ben capito dicono che Chrome restituisce un array di
elementi ma, onestamente, a me non risulta. Quindi direi o che su Stack
Overflow hanno fatto un po' di casino, oppure questa cosa era vera nelle
vecchie versioni ed è stata fixata.
 
Aggiungo che in HTML5 non tutti i tag debbano essere chiusi, visto che
lo menzioni, e che se un browser è flessibile tanto da accettare alcune
cose – non esplode se imposti due elementi con lo stesso ID - questo non
significa che si debba comportare anche come ti aspetti. Anzi, spesso i
comportamenti variano da vendor a vendor, come è stato detto da
Cristiano, giacché gli standard non lo specificano.
 
Detto ciò, viste le premesse che hai fatto, puoi ottenere una lista di
tag aventi lo stesso id usando `querySelectorAll`:
 
    document.querySelectorAll("[id=foo]");
 
Ovviamente laddove supportato. Altrimenti devi ripiegare su jQuery / Sizzle.
 
Conta che, una pagina che contenga piú elementi aventi lo stesso ID,
potrebbe comunque comportarsi "male". Il mio consiglio è, se temi che
possa esserci un pericolo del genere (che lo sviluppatore stia usando lo
stesso ID piú volte), di fare un warning piú che cercare di far
funzionare il tutto; perché potresti comunque ottenere dei comportamenti
che non ti aspetti. Qualcosa tipo:
 
    var nodes = document.querySelectorAll("[id=foo]");
 
    if (nodes.length > 1)
        // Attenzione! Il codice rischia di comportarsi in modo anomalo
 

 generale ai successivi? Grazie.
 
Devi usare il name. Lo stesso name puoi darlo a più elementi html e recuperarli tramite document.getElementsByTagName('')
 

 Devi usare il name.
 
Sfortunatamente questo vale solo per alcuni elementi, ovvero i form
elements. Il name non ï¿½ un attributo valido per elementi come il DIV, ad
esempio.
 
Inoltre l'use case dell'OP ï¿½ che non ï¿½ lui a scrivere l'HTML della
pagina, come ha detto in un successivo post ï¿½ che perï¿½, a quanto pare,
non tutti hanno ricevuto vedasi me, l'ho trovato su google groups ï¿½ e
quindi ha bisogno di verificare che chi ha scritto la pagina, non abbia
fatto errori aggiungendo lo stesso ID per piï¿½ elementi, e nel qual caso
recuperarli tutti.
 
ï¿½ una situazione un po' particolare onestamente, per quanto mi riguarda
ï¿½ giusto che se uno sviluppatore scrive il codice malamente non ottenga
i risultati desiderati: il fatto di "correggere gli errori altrui" fu il
problema principale di IE, che all'epoca digeriva ogni tipo di codice
che gli veniva dato in pasto, anche con risultati bizzarri, contribuendo
cosï¿½ a formare sviluppatori web incapaci ï¿½ perchï¿½ non imparavano ï¿½ e il
famoso detto "Eh, ma su IE funziona" (certo, finchï¿½ poi non incappavano
appunto in comportamenti assurdi dati dal codice mal funzionante che
avevano scritto).


Non devi spiegare l'html a me, dobbiamo dare una soluzione a oss che potrebbe usare:
  - document.getElementById('') per recuperare un elemento per id. l'id è univoco
  - document.getElementsByName('') per recuperare elementi per nome. non tutti gli elementi supportano il name
  - document.getElementsByTagName('') per recuperare gli elementi per tag
  - document.getElementsByClassName('') per recuperare gli elementi per classe. valido per tutti i tag
 
Spero di essere stato di aiuto. ciao

 Spero di essere stato di aiuto. ciao
 
I contributi nei NG sono sempre d'aiuto, perchï¿½ fanno nascere
discussioni utili; anche per i posteri. :)