Tutto giusto quello che dice Xinod, vorrei spendere due parole in più su:
Originariamente inviato da Xinod
è qui l' errore
var recupera= (document.all) ? document.all : document.getElementById;
sostituiscilo con una funzione a parte
function recupera(name_ID) {
return (document.all)?document.all[name_ID]: (document.getElementById)?document.getElementById( name_ID):null
}
Il problema è lo scoping.
Il codice scritto da oronze, usato per evitare di riscrivere continuamente lo stesso codice, può nascondere come in questo caso bug difficili da individuare (almeno le prime volte....soprattutto se si testa solo su Explorer).
Il problema, dicevo, riguarda lo scope delle funzioni chiamate, ovvero, il "contesto in cui i riferimenti usati dalle funzioni sono validi" (passatemi la definizione stringata
).
Nel dettaglio, con:
codice:
var recupera= (document.all) ? document.all : document.getElementById;
l'intenzione è quella di associare a "recupera" un puntatore a funzione (in maniera crossbrowser). Il problema è che la funzione non è una funzione globale, ma un metodo dell'oggetto document (nel quale metodo si possono avere riferimenti all'oggetto stesso).
Il codice sopra decontestualizza il metodo, ovvero fa sì che "recupera" sia uguale al puntatore a funzione cercato, ma il contesto (lo scope) in cui viene introdotto non è più quello corretto (cioè quello di document).
Per capirci meglio faccio un esempio:
codice:
Forum = {
nome : "Scripting",
avvisa : function(){alert("sei nel forum "+this.nome)}
}
supponiamo di voler chiamare il metodo "avvisa" all'onload. Quello che occorre fare è assegnare al gestore d'evento onload un puntatore alla funzione che vogliamo lanciare.
Se facessimo però:
codice:
onload = Forum.avvisa
avremo correttamente assegnato ad onload un puntatore a funzione, ma questa verrebbe decontestualizzata e portata nello scope di window e non di Forum.
Quello che occorre fare è quindi assegnare ad onload un puntatore a funzione che consenta di conservare correttamente lo scope del metodo:
codice:
onload = function(){Forum.avvisa();}
Ho usato la funzione anonima, ma potevo usare qualsiasi altra funzione contenitore, l'importante è che al suo interno faccia la chiamata utilizzando i giusti riferimenti.
In pratica questa funzione contenitore è la stessa usata da Xinod per il recupera che consente:
1) di risparmiare bytes da caricare, evitando di riscrivere ogni volta il codice crossbrowser.
2) di rendere il codice più leggibile
3) di effettuare la chiamata in maniera corretta
Va infine detto che oronze probabilmente non si è accorto dell'origine del problema perchè il suo codice probabilmente funziona su Explorer.
Essendo codice "nativo" la mia è una supposizione, ma credo che per Explorer sia "corretto", per il fatto che consente di accedere ad un qualsiasi elemento utilizzando una variabile che abbia come nome il valore dell'attributo ID. Questo dimostra un legame molto stretto tra lo scope di document.all e quello globale (di window).
Questa scelta di Explorer è proprio brutta a mio avviso e nasconde magagne come questa.
in sostanza occhio allo scoping e non testate le cose solo su Explorer.
ciauzz