addEventListener e il target di riferimento

MarcoGrazia

Utente Attivo
15 Dic 2009
813
18
18
60
Udine
www.stilisticamente.com
Ciao,
una domanda forse un po' da newbie ma necessaria.

Sto cercando di identificare (tramite javascript) tutti i click sulle ancore, ed ho iniziato con un semplice addEventListener() associato ad A.
Mi ha dato errore, ancora.addEventListener() non è una funzione.
Il codice:
JavaScript:
var ancora = document.getElementsByName('a');
ancora.addEventListener('click', function(event) {   //   <---- Punto di errore

});

Ora se ricordo bene, e la pagina https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener mi è d'aiuto, non mi pare di aver fatto errori, ma forse sbaglio. Forse, non devo utilizzare la getElementsByName() ma allora dovrei almeno identificare ogni ancora singolarmente e associare a tutte lo stesso evento.
Come risolvo?

Ah, la pagina ha ancore al suo interno.
 

WmbertSea

Utente Attivo
28 Nov 2014
211
33
28
Ciao, non sei molto lontano dalla soluzione ma ti manca qualche nozione in più da conoscere, qualche procedimento in più da applicare e sopratutto qualche granchio da evitare.

Nozione:
A differenza di getElementById(), il quale restituisce un unico elemento, il metodo getElementsByName(), come vari altri, restituisce una collection NodeList, cioè una sorta di vettore di tutti gli elementi selezionati.

Il metodo addEventListener() può essere applicato al singolo elemento, non ad una collection; da qui l'errore che ricevi, perché la collection NodeList non possiede di fatto tale funzione.

Procedimento:
A tal proposito dovrai eseguire un ciclo su tale vettore per poter "identificare" i singoli elementi e applicare a quel punto il listener. Più o meno come hai supposto tu stesso.

Puoi fare una cosa del genere con un semplice ciclo for:
JavaScript:
var ancore = document.getElementsByName('a');
for(let i = 0; i < ancore.length; i++){
   ancore[i].addEventListener('click', function(event) {
      //... resto del codice
   });
}

Granchio da evitare:
Occhio alle sviste. Tutto funzionerebbe se tu volessi selezionare degli elementi (che siano ancore o no*) ai quali è applicato l'attributo "name" col valore "a":

Esempio:
Codice:
<a href="#" name="a">A</a>
<br>
<input type="checkbox" name="a">
<br>
<span name="a">B</span>
<script>
  var ancore = document.getElementsByName('a');
  for (let i = 0; i < ancore.length; i++) {
    ancore[i].addEventListener('click', function(event) {
      event.preventDefault();
      console.log("Hai cliccato su ", this);
    });
  }
</script>
* generalmente il "name" è supportato solo per particolari elementi, come gli elementi di controllo nei form.

La documentazione, riguardo il metodo getElementsByName(), parla chiaro: "Collection of elements with a given name attribute"

Deduco invece che tu volessi utilizzare il metodo getElementsByTagName(), il che, avrebbe più senso. Anche in questo caso il discorso "collection" resta uguale:
Codice:
<a href="#A">A</a>
<br>
<a href="#B">B</a>
<br>
<a href="#C">C</a>
<script>
  var ancore = document.getElementsByTagName('a');
  for (let i = 0; i < ancore.length; i++) {
    ancore[i].addEventListener('click', function(event) {
      event.preventDefault();
      console.log("Hai cliccato su ", this);
    });
  }
</script>

Chiaramente si può risolvere in vari altri modi.

Spero di aver chiarito qualche perplessità.
Buon proseguimento.
 

MarcoGrazia

Utente Attivo
15 Dic 2009
813
18
18
60
Udine
www.stilisticamente.com
Ciao, in realtà non ho dovuto fare tutto quel che hai fatto tu, ma ho risolto in altro modo.

In realtà so bene la differenza tra getElementById e getElementsByName, solo speravo che addEventListener accettasse una lista di elementi e non il riferimento ad uno e solo uno.

non è così e pazienza, si trova un'altra strada come hai fatto tu :)
A proposito piccolo stupido consiglio, invece di usare name in span, che non è supportato (fonte whatwg https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-span-element) puoi utilizzare dataSet.

Ad ogni modo ho risolto dando document in pasto ad addEventListener e funziona, anzi, è proprio questo che mi aveva portato fuori strada, pensavo se accetta document che si porta con se tutto l'intero documento, strano che non accetta una porzione dello stesso.

Quindi:
JavaScript:
<!DOCTYPE html>
<html lang="it" dir="ltr">
    <head>
        <title>Prova</title>
    </head>
    <body>
        <textarea></textarea>
        <ul>
            <li><a href="#ciccio">Ciccio</a></li>
            <li><a href="#pluto">Pluto</a></li>
            <li><a href="#paperino">Paperino</a></li>
        </ul>
        <script>
            document.addEventListener('click', function(evt) {
                var hash = '';
                switch (evt.currentTarget.activeElement.localName) {
                    case 'a':
                        var hash = evt.currentTarget.activeElement.hash;
                        break;
                    default:
                        evt.preventDefault();
                }
            }, false);
        </script>
    </body>
</html>
In pratica , creato l'evento da associare all'intero document, una volta cliccato su un punto della pagina, se questo è l'ancora, posso estrarne l'hash (o l'url, o il testo o qualsiasi altra parte dell'ancora) oppure, gestire qualsiasi altro elemento della pagina ( per questo ho utilizzato uno switch anche se qui sembra inutile e bastava un semplice selettore if ).

Il preventDefault alla fine mi serve a cancellare l'evento quando non è sull'elemento cercato.

Funziona, non devo ciclare nulla e mi basta un solo gestore di evento.
 
Discussioni simili
Autore Titolo Forum Risposte Data
B gestione eventi con addEventListener,comportamento strano dell'handle Javascript 2
A Numero di parametri addEventListener per i diversi browser Javascript 0
N problema parametro funzione addEventListener Javascript 2
S Realizziamo siti web/ pubblicita di target Offerte e Richieste di Lavoro e/o Collaborazione 0
amaranthinemess [HTML] :target e :hover HTML e CSS 5
Z Acquisto account instagram target tech da 30k in su Annunci servizi di Social Media Marketing 1
H [CERCO] Pag. facebook 50k+ ( target italia, nord italia ) Annunci servizi di Social Media Marketing 0
VPonticelli [VENDO] Profilo Instagram da 172K attivissimo, seguaci italiani, ottimo target Annunci servizi di Social Media Marketing 6
G [CERCO] Pagina Facebook tema cucina target 18-24 Annunci servizi di Social Media Marketing 2
Z acquisto pagina fan con target donne Presentati al Forum 0
I [COMPRO] pagine dai 1000 ai 5000 like, utenti reali, preferenza target femminile Annunci servizi di Social Media Marketing 8
C [PHP] Upload immagine in un form con target _blank: non funziona PHP 7
A Come mettere il target _blank in un parser xml in php? PHP 1
P attributo target dinamico in JS Javascript 0
P [VENDO] Invii DEM internazionali o nazionali, con scelta 3 target Vendere e Acquistare pubblicita' online 0
P [VENDO] Invii DEM internazionali o stranieri, con scelta 3 target Email Marketing 0
P [VENDO] Traffico Internazionale Facebook con target - Massimo 15k visualizzazioni/gg Vendere e Acquistare pubblicita' online 0
T [Vendo] Liste 15k email target alimentare Vendere e Acquistare pubblicita' online 0
Shyson Mettere target="_top" PHP 0
Frank10 [Compro] Pagine target scommesse e gioco Annunci servizi di Social Media Marketing 1
V [COMPRO] Spazi pubblicitari su siti target DONNA Vendere e Acquistare pubblicita' online 0
V [COMPRO] Acquisto con ottimo budget pagine fan facebook con tema musicale o con target giovanile Annunci servizi di Social Media Marketing 1
Z specificare target in form Javascript 1
F problema Pulsanti flash su IE con target su diversi frame Flash 3
borgo italia target HTML e CSS 1
S Domanda semplice per con SCENE e TARGET Flash 1
S Target HTML e CSS 42
M script con "target" Javascript 1
A AIUTO target="_self" non va HTML e CSS 3
S [Javascript] [HTML] creare stringhe di riferimento da riutilizzare Javascript 5
C [Javascript] cambio dinamico riferimento elemento html Javascript 2
S [PHP] Selezione dati con riferimento ad altra colonna tabella PHP 22
P Problema riferimento al click jQuery 1
V Passaggio riferimento classe Flash 3
I estrarre record da 2 tabelle mysql con riferimento id_utente uguale Database 3
Z Leggere feed rss xml con link di riferimento in .aspx PHP 4
M Riferimento alla classe di una pagina aspx ASP.NET 2
G riferimento ad una immagine Javascript 0
M passaggio per riferimento Programmazione 0
C A.C.S. - Un punto di riferimento per la protezione del tuo lavoro. Presenta il tuo Sito 2

Discussioni simili