Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    jquery onclick href funziona solo una volta

    Ciao a tutti, sono un novizio con jquery e ho il seguente problema che mi sta facendo ammattire:
    nella mia pagina ho 4 link ognuno dei quali, se cliccato, tramite l'evento onclick ricrea la porzione di html che contiene i link facendo in modo che quello che è stato cliccato risulti evidenziato e non più cliccabile.
    Funziona, ma solo la prima volta che clicco su un link dopo aver caricato la pagina. Tutte le altre volte non funziona più e viene inserita l'ancora sull'url della pagina.
    Per capirci:

    la mia pagina prova.html è così fatta:

    codice:
    <html>   <head>    
         <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> 
            </script>           
       </head>
       <body>  
          <main class="main">          
                <ul class="filter-menu">            
                   <li id="tab_a"><b><span>Tabellone A</span></b></li>
                   <li id="tab_b"><a class ="active" id = "B" href="#" title="Tabellone B"><span>Tabellone B</span></a></li>
                   <li id="tab_c"><a class ="active" id = "C" href="#" title="Tabellone C"><span>Tabellone C</span></a></li>
                   <li id="tab_d"><a class ="active" id = "D" href="#" title="Tabellone D"><span>Tabellone D</span></a></li>                         
                </ul>
       </body>
    </html>
    <script>
    $(document).ready(function(){
        $("a.active").on('click', function(e) {
            
                var tab=$(this).attr("id");
                if(tab=='A') {
                    $("li#tab_a").html('<b><span>Tabellone A</span></b>');
                    $("li#tab_b").html('<a class ="active" id = "B" href="#"><span>Tabellone B</span></a>');
                    $("li#tab_c").html('<a class ="active" id = "C" href="#"><span>Tabellone C</span></a>');
                    $("li#tab_d").html('<a class ="active" id = "D" href="#"><span>Tabellone D</span></a>');
                    
                }
                if(tab=='B') {
                    $("li#tab_a").html('<a class ="active" id = "A" href="#"><span>Tabellone A</span></a>');
                    $("li#tab_b").html('<b><span>Tabellone B</span></b>');
                    $("li#tab_c").html('<a class ="active" id = "C" href="#"><span>Tabellone C</span></a>');
                    $("li#tab_d").html('<a class ="active" id = "D" href="#"><span>Tabellone D</span></a>');
                    
                }
                if(tab=='C') {
                    $("li#tab_a").html('<a class ="active" id = "A" href="#"><span>Tabellone A</span></a>');
                    $("li#tab_b").html('<a class ="active" id = "B" href="#"><span>Tabellone B</span></a>');
                    $("li#tab_c").html('<b><span>Tabellone C</span></b>');
                    $("li#tab_d").html('<a class ="active" id = "D" href="#"><span>Tabellone D</span></a>');
                    
                }
                if(tab=='D') {
                    $("li#tab_a").html('<a class ="active" id = "A" href="#"><span>Tabellone A</span></a>');
                    $("li#tab_b").html('<a class ="active" id = "B" href="#"><span>Tabellone B</span></a>');
                    $("li#tab_c").html('<a class ="active" id = "C" href="#"><span>Tabellone C</span></a>');
                    $("li#tab_d").html('<b><span>Tabellone D</span></b>');
                    
                }        
                e.preventDefault();     
            });
    });    
    </script>
    La situazione di partenza è quella in cui il link attivo è quello relativo al tabellone A e non è cliccabile per cui al caricamento della pagina vedo:



    I link cliccabili sono B, C e D. Se clicco ad esempio su B succede quello che mi aspetto, ovvero che l'html dei link venga rimodellato in questo modo, rendendo attivo il link B:




    Game over. Non posso più cliccare su gli altri link attivi perché non succede più niente tranne il fatto che viene generata un'ancora sull'url della mia pagina che diventa pagina.html#

    Mi pare di aver capito, facendo delle ricerche sui vari forum, che se si generano dinamicamente degli elementi sui quali si vuole poter richiamare l'evento onclick ci sono dei problemi ma non ho capito se e come si possono risolvere. Qualcuno ha una soluzione per me, ammesso che esista?
    Grazie.

  2. #2
    Moderatore di Javascript L'avatar di ciro78
    Registrato dal
    Sep 2000
    residenza
    Napoli
    Messaggi
    8,514
    infatti è come dici.

    se non erro dovrebbe essere sufficiente fare questo
    codice:
    $(document).on('click','.active', function(e) {
    comunque riscrivere tutti i tab non la migliore delle soluzioni. normalmente si dovrebbe agire usando css per renderizzare gli elementi come link o meno. ovviamente lato js verifichi poi se il link è attivo e non applichi azioni.
    Ciro Marotta - Programmatore JAVA - PHP
    Preferisco un fallimento alle mie condizioni che un successo alle condizioni altrui.


  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Mi pare di aver capito, facendo delle ricerche sui vari forum, che se si generano dinamicamente degli elementi sui quali si vuole poter richiamare l'evento onclick ci sono dei problemi ma non ho capito se e come si possono risolvere. Qualcuno ha una soluzione per me, ammesso che esista?
    Ciao e benvenuto, sì, ciò che hai trovato è corretto e si può risolvere; in jQuery puoi adoperare quella tecnica chiamata "event delegation"

    La causa del problema si trova nel modo che usi per assegnare il gestore del click per quegli elementi.
    Sostanzialmente utilizzi questo script:
    codice:
    $("a.active").on('click', function(e) {
    dove il selettore si riferisce direttamente agli elementi selezionati a cui vuoi applicare il gestore click.

    Questo script, essendo eseguito giusto una prima volta al caricamento della pagina, seleziona quegli elementi e applica correttamente il gestore. Da precisare che ogni oggetto sulla pagina ha una sua specifica identità nel momento in cui viene creato e finché resta presente nella pagina (in senso lato), ma quando l'oggetto non esiste più, tutti i riferimenti a questo sono persi.

    Questi elementi vengono infatti "distrutti"; perciò, qualsiasi proprietà, metodo o riferimento che questi possedevano, cessa di esistere e risulterà chiaramente inesistente dopo la loro distruzione. Il fatto che tu stia ricreando poi una "simil-copia" di quel codice HTML (anche se gli elementi e gli id usati risultano uguali ai precedenti) non determina la riassegnazione degli stessi gestori applicati agli elementi iniziali perché si tratta sostanzialmente di oggetti diversi.

    Va da sé che il comportamento da te rilevato sia più che lecito e quantomeno logico secondo questo ragionamento.

    Per risolvere, in jQuery generalmente si utilizza la tecnica della delegazione. Sostanzialmente, per un dato elemento (o meglio, per ciascuno degli elementi restituiti da uno specifico selettore jQuery), la gestione di un qualsivoglia suo evento viene delegata ad un suo elemento ascendente, il quale si è sicuri che non venga distrutto; in questo modo si ha certezza che il gestore applicatogli (con delega) sia mantenuto "in vita" anche quando l'elemento diretto, a cui questo si riferisce, viene a mancare.

    Quando viene ricreato un elemento simile (identificabile attraverso lo stesso selettore jQuery usato per la delega) jQuery provvederà a riassegnargli anche i gestori degli eventi definiti attraverso quella precedente delega.

    L'elemento delegato può essere il diretto genitore dell'elemento specificato o un qualsiasi suo discendente nella struttura gerarchica del documento fino ad arrivare all'oggetto radice "document"

    Puoi utilizzare ad esempio una sintassi del genere:
    codice:
    $(document).on('click', 'a.active', function(e) {
    .
    Qui un articolo per approfondire sul lato tecnico:
    jQuery, event delegation senza segreti



    PS: giusto un mio personale parere; trovo l'impostazione del tuo script abbastanza ridondante (leggasi, codice ripetitivo che potrebbe essere adeguatamente sfoltito); personalmente risolverei in modo più "dinamico" magari usando un unico blocco HTML che sia rimodellato opportunamente, lasciando invariate le parti fisse e integrando con delle condizioni solo i dati significativi. Posso però intuire che quello da te postato sia solo un esempio di un elaborato più esteso, per cui mi limito solo a fare questa osservazione sul codice qui presente.




    EDIT: pardon, ho visto solo ora che ciro78 aveva appena risposto; riassume grossomodo tutto ciò che ho indicato qui, compreso il codice ridondante


    EDIT2: anzi... la soluzione CSS accennata da ciro è sicuramente la strada migliore da seguire
    Ultima modifica di KillerWorm; 23-11-2019 a 14:06
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4

    EDIT

    Grazie a entrambi per avermi risposto. In particolare apprezzo la spiegazione teorica del perché il codice che avevo scritto non funzionava, anche se in qualche modo l'avevo intuito. Sostanzialmente applicavo l'evento onclick a degli elementi che poi venivano sostituiti dinamicamente da delle copie che, pur avendo gli stessi id, non erano cmq gli stessi elementi.
    A questo punto che mi è chiaro (a proposito: la soluzione che mi avete indicato funziona) mi occuperò della ridondanza del codice. Per me l'importante era farvi capire il contesto generale e quello che volevo che succedesse, ora posso curare i dettagli.
    Grazie ancora.

    P.S. potrei avere un esempio della soluzione css indicata da Ciro?
    Ultima modifica di joeforte75; 23-11-2019 a 15:07 Motivo: Dimenticanza

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Errata corrige:
    Quote Originariamente inviata da KillerWorm
    L'elemento delegato può essere il diretto genitore dell'elemento specificato o un qualsiasi suo -discendente- ascendente nella struttura gerarchica


    Quote Originariamente inviata da joeforte75
    Grazie a entrambi per avermi risposto. In particolare apprezzo la spiegazione teorica del perché il codice che avevo scritto non funzionava, anche se in qualche modo l'avevo intuito.
    Felice d'essere stato utile

    Quote Originariamente inviata da joeforte75
    Per me l'importante era farvi capire il contesto generale e quello che volevo che succedesse
    Chiaro

    Quote Originariamente inviata da joeforte75
    P.S. potrei avere un esempio della soluzione css indicata da Ciro?
    Anticipo ciro; la cosa può essere ovviamente impostata in millemila modi, di base potrebbe essere una cosa del genere:
    codice:
    <!DOCTYPE HTML>
    <html lang="it">
      <head>
        <title>Esempio</title>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>
          $(function(){
            $('.filter-menu a').click(function(){
            
             // Attraverso una classe gestitsco l'attivazione della voce cliccata
             $('.filter-menu a.active').removeClass('active');
             $(this).addClass('active');
             
             // ... e qui faccio qualcos'altro
             
            });
          });
        </script>
        <style>
          /* Formatto e rendo non cliccabile la voce attiva  */
          a.active {
             pointer-events: none;
             text-decoration: none;
             font-weight: bold;
             color: black;
          }
        </style>
      </head>
      <body>
          <ul class="filter-menu">            
             <li id="tab_a"><a href="#" class="active">Tabellone A</a></li>
             <li id="tab_b"><a href="#">Tabellone B</a></li>
             <li id="tab_c"><a href="#">Tabellone C</a></li>
             <li id="tab_d"><a href="#">Tabellone D</a></li>                   
          </ul>
      </body>
    </html>
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Tutto molto chiaro, grazie mille.

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.