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

    Script funziona solo se mal posizionato

    Ciao a tutti, ho un problema che spero possiate aiutarmi a risolvere.

    Utilizzo il seguente script per gestire una gallery nel mio sito:

    codice:
    <script>
    
    function openModal() {
    $("#myModal").fadeIn(300);
      document.getElementById("myModal").style.display = "block";
    }
    
    
    function closeModal() {
      var modal = document.getElementById("myModal");
      $(modal).fadeOut(300);
    }
    
    
    var modal = document.getElementById("myModal");
    modal.addEventListener('click', function(e) {
      if (e.target === modal) {
        closeModal();
      }
    });
    
    
    var slideIndex = 1;
    showSlides(slideIndex);
    
    
    function plusSlides(n) {
      var slides = $(".mySlides");
      var currentIndex = slideIndex - 1;
      var nextIndex = currentIndex + n;
    
    
      if (nextIndex < 0) {
        nextIndex = slides.length - 1;
      } else if (nextIndex >= slides.length) {
        nextIndex = 0;
      }
    
    
      var currentSlide = $(slides[currentIndex]);
      var nextSlide = $(slides[nextIndex]);
    
    
      currentSlide.fadeOut(500);
      nextSlide.fadeIn(500, function() {
        currentSlide.hide();
        nextSlide.css("display", "block");
        slideIndex = nextIndex + 1;
      });
    
    
    
    
       // aggiorna la classe active della thumbnail corrente
      var dots = document.getElementsByClassName("demo");
      for (var j = 0; j < dots.length; j++) {
        if (j === nextIndex) {
          dots[j].className += " active";
        } else {
          dots[j].className = dots[j].className.replace(" active", "");
        }
      }
    }
    
    
    function currentSlide(n) {
      var slides = $(".mySlides");
      var dots = $(".demo");
    
    
      // aggiorna slideIndex con il valore dell'immagine miniatura cliccata
      slideIndex = n;
    
    
      // nascondi tutti gli altri slide tranne quello corrente
      for (var i = 0; i < slides.length; i++) {
        if (i !== n - 1) {
          $(slides[i]).fadeOut(500);
        }
      }
    
    
      // applica l'effetto fade al slide corrente
      $(slides[n - 1]).fadeIn(500);
    
    
      // aggiorna la classe active della thumbnail corrente
      for (var j = 0; j < dots.length; j++) {
        if (j === n - 1) {
          dots[j].className += " active";
        } else {
          dots[j].className = dots[j].className.replace(" active", "");
        }
      }
    }
    
    
    function showSlides(n) {
      var i;
      var slides = document.getElementsByClassName("mySlides");
      var dots = document.getElementsByClassName("demo");
      var captionText = document.getElementById("caption");
      if (n > slides.length) {slideIndex = 1}
      if (n < 1) {slideIndex = slides.length}
      for (i = 0; i < slides.length; i++) {
          slides[i].style.display = "none";
      }
      for (i = 0; i < dots.length; i++) {
          dots[i].className = dots[i].className.replace(" active", "");
      }
      slides[slideIndex-1].style.display = "block";
      dots[slideIndex-1].className += " active";
      captionText.innerHTML = dots[slideIndex-1].alt;
    }
    </script>
    In precedenza questo script era posizionato erroneamente nella struttura html, in quanto stava dopo il tag di chiusura </html>.

    Ciò nonostante funzionava correttamente.

    Adesso, per evidenti ragioni di pulizia e validazione del codice, ho posizionato lo script tra i tag "head".

    Da quando ho fatto questo lo script continua a funzionare, ma ha perso una delle sue caratteristiche.

    Infatti avevo implementato una funziona per cui al clic in un punto a caso della pagina, al di fuori della gallery, quest'ultima si chiudeva.

    Prima dello spostamento, quando lo script era posizionato dopo il tag </html>, la sopra descritta funzione di chiusura funzionava.

    Adesso non funziona più e la gallery si può chiudere solo con il classico click sulla X che ho posizionato in alto a destra.

    Avete idea di quale possa essere la causa di tale comportamento?

    Perché se mal posizionato lo script funzionava e adesso che è correttamente posizionato presenta questo difetto?

    Grazie per il supporto!

  2. #2
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Ciao, difficile da capire senza vedere la pagina in azione.

    Nella console salta fuori qualche errore di script?
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  3. #3
    Buongiorno Killer, ho importanti aggiornamenti.

    Il problema riguardava con tutta evidenza il fatto che posizionavo male lo script, anche dopo la "correzione" che mi sembrava opportuna.

    Ho capito infatti che al posto di infilare il link nei tag head presenti dell'header.php del mio tema wordpress, conviene (anzi, è più giusto) utilizzare la funzione "wp_enqueue_script" in functions.php.
    Ovviamente per linkare correttamente lo script l'ho prima inserito in un file e gli ho dato un nome.
    Poi l'ho linkato in functions.php in questo modo:

    wp_enqueue_script('gallery-script', get_template_directory_uri() . '/js/gallery-script.js', array('jquery'), '1.0', true);

    E infine ho cancellato lo script dall'header.php.

    Ho capito anche che così facendo lo script viene caricato prima del tag body di chiusura e non tra i tag head.

    Sempre se ho capito bene, da alcuni anni questa metodologia è considerata quella corretta.

    In definitiva adesso funziona di nuovo tutto bene.

    Vorrei sapere intanto se quanto ho scritto ed interpretato è corretto.

    In secondo luogo approfitto per esporre un problema collegato.

    Mediante il sistema illustrato poc'anzi ho eliminato dai tag head tutti i link a file css e gli script, utilizzando la funzione di richiamo in functions.php.

    E' rimasto solo uno script però che se lo rimuovo dai tag head, smette di funzionare, nonostante il richiamo fatto in functions.php.

    Si tratta di questo richiamo a jquery che ho nei tag head:

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    Senza questa stringa di codice nei tag head, lo script postato in apertura non funziona correttamente.

    Tutto questo è strano, anche perché wordpress ha lo script jquery aggiornato di default, in teoria non mi servirebbe richiamarlo.

    Infatti in altre pagine del sito, che fanno uso di jquery, non lo richiamo.

    Eppure per lo script postato in apertura, senza uno specifico richiamo a quella speficia versione di jquery tra i tag head dell'header, non funziona bene.

    E' come se lo script funzionasse in parte grazie al jquery di default di wordpress ed in parte grazie a quello poc'anzi linkato e posizionato tra i tag head.

    Ieri ci ho perso una serata senza riuscire a risolvere...vi viene in mente qualche soluzione?

  4. #4
    Per rispondere alla domanda di Killer sul log.

    Se tengo
    codice:
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> 
    nei tag head, non da alcun errore e tutto funziona bene.

    Se elimino quella parte di codice dall'head, la gallery non funziona più e nel log leggo questo errore:

    "Uncaught TypeError: $ is not a function
    at showSlides (gallery-script.js?ver=1.0:82:16)
    at gallery-script.js?ver=1.0:19:1"

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Non so, potrebbe essere che lo script della galleria sia eseguito comunque prima dell'inclusione di jQuery. Bisognerebbe vedere la pagina in azione per capire cosa avviene.

    Infatti l'errore "$ is not a function" è generalmente dato dal fatto che jQuery (sempre che la variabile $ faccia riferimento a tale libreria) non è stata inclusa correttamente o risulta comunque inclusa dopo l'esecuzione degli script che ne fanno uso.

    Presumo tu sappia già (ma è sempre bene tenerlo presente) che la libreria jQuery, come vari altri framework, deve essere inclusa necessariamente "prima" degli script che ne fanno uso.

    In genere è possibile includere qualsiasi script sia nell'<head> sia nel <body>, non c'è una regola fissa o un metodo più corretto dell'altro ma la sostanziale differenza sta nel fatto che quando si inserisce uno script in <head> il DOM (cioè tutti i contenuti HTML della pagina) non sono ancora stati creati e non possono essere quindi manipolati, perché la lettura del documento HTML (nella fase di parsing) avviene dall'alto al basso e gli elementi vengono creati di volta in volta durante questa fase.

    Se si esegue uno script che deve far riferimento ad un qualche elemento presente nella pagina, deve essere eseguito dopo che l'elemento è stato creato e quindi risulta disponibile. Un tale script lo si può includere in <head> ma sarà necessario eseguirlo tramite un qualche evento che determini almeno l'avvenuto caricamento del DOM; vedi l'evento DOMContentLoaded o l'analogo metodo ready() (di jQuery). Ovviamente questo accorgimento non serve se lo stesso script viene incluso (e quindi eseguito) alla fine del <body>; in tal caso infatti il contenuto del DOM è presumibilmente già disponibile. Per tale motivo si tende ad inserire gli script alla fine del body, ma in alcuni casi potrebbe risultare più comodo inserirli in <head>.

    Nella funzione wp_enqueue_script l'ultimo parametro ($in_footer) stabilisce se includere lo script alla fine del <body> o viceversa in <head>.

    Librerie/framework possono essere incluse (e forse sarebbe meglio) in <head> così che queste siano disponibili quando "interpellate" dagli script eseguiti di seguito, evitando magari anche errori tipo quello da te riportato. Gli script che si basano su tali librerie possono invece essere posti alla fine del <body>, soprattutto se fanno riferimento ad elementi del DOM, come già spiegato sopra.

    Non so dirti riguardo jQuery di default in WP, bisognerebbe capire appunto cosa avviene nella pagina in azione, ma se fosse necessario includere versioni differenti di tale libreria (per il corretto funzionamento di eventuali plugin) va utilizzato opportunamente il metodo noConflict(). Non so se nel tuo caso sia necessario; bisogna capire se effettivamente viene incluso jQuery di default (che dal log pare di no) e se quella gallery funziona con tale versione.

    Per ora è tutto, fai sapere.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Alla fine il mio amico chatGPT mi ha consigliato di usare questo approccio, che di fatto funziona.
    La seguente regola è stata applicata in maniera condizionale, così che funzioni solo nella pagina dove ho lo script incriminato.

    codice:
     wp_deregister_script('jquery');
    	    wp_enqueue_script('jquery', 'https://code.jquery.com/jquery-3.7.0.min.js', array(), '3.7.0');
    Pensi che possa andar bene?

    Certo, avrei preferito riuscire a far funzionare il jquery di wordpress e mi da un pò fastidio dover adottare una soluzione di ripiego senza riuscire a comprendere le ragioni per cui in questo modo funziona e nell'altro no.

    Tuttavia, dopo innumerevoli tentativi, non ho trovato nulla di meglio.

    Eventualmente, se non ti chiedo troppo, potresti fare una verifica sulla pagina in oggetto per vederla in azione?

    Si tratta della homepage del mio sito (le tue credenziali di accesso sono sempre valide).

    La gallery è quella in fondo alla pagina.
    Lo script di riferimento lo trovi nella sezione "editor del tema" di wordpress, cartella JS, si chiama "Gallery-script".

    Riporto comunque qui il suo intero contenuto:

    codice:
    function openModal() {  $("#myModal").fadeIn(300);
      document.getElementById("myModal").style.display = "block";
    }
    
    
    function closeModal() {
      var modal = document.getElementById("myModal");
      $(modal).fadeOut(300);
    }
    
    
    
    
      var modal = document.getElementById("myModal");
      modal.addEventListener('click', function(e) {
        if (e.target === modal) {
          closeModal();
        }
      });
    
    
      var slideIndex = 1;
      showSlides(slideIndex);
    
    
      function plusSlides(n) {
        var slides = $(".mySlides");
        var currentIndex = slideIndex - 1;
        var nextIndex = currentIndex + n;
    
    
        if (nextIndex < 0) {
          nextIndex = slides.length - 1;
        } else if (nextIndex >= slides.length) {
          nextIndex = 0;
        }
    
    
        var currentSlide = $(slides[currentIndex]);
        var nextSlide = $(slides[nextIndex]);
    
    
        currentSlide.fadeOut(500);
        nextSlide.fadeIn(500, function() {
          currentSlide.hide();
          nextSlide.css("display", "block");
          slideIndex = nextIndex + 1;
        });
    
    
        // aggiorna la classe active della thumbnail corrente
        var dots = document.getElementsByClassName("demo");
        for (var j = 0; j < dots.length; j++) {
          if (j === nextIndex) {
            dots[j].className += " active";
          } else {
            dots[j].className = dots[j].className.replace(" active", "");
          }
        }
      }
    
    
      function currentSlide(n) {
        var slides = $(".mySlides");
        var dots = $(".demo");
    
    
        // aggiorna slideIndex con il valore dell'immagine miniatura cliccata
        slideIndex = n;
    
    
        // nascondi tutti gli altri slide tranne quello corrente
        for (var i = 0; i < slides.length; i++) {
          if (i !== n - 1) {
            $(slides[i]).fadeOut(500);
          }
        }
    
    
        // applica l'effetto fade al slide corrente
        $(slides[n - 1]).fadeIn(500);
    
    
        // aggiorna la classe active della thumbnail corrente
        for (var j = 0; j < dots.length; j++) {
          if (j === n - 1) {
            dots[j].className += " active";
          } else {
            dots[j].className = dots[j].className.replace(" active", "");
          }
        }
      }
    
    
      function showSlides(n) {
        var i;
        var slides = $(".mySlides");
        var dots = $(".demo");
        if (n > slides.length) { slideIndex = 1 }
        if (n < 1) { slideIndex = slides.length }
        for (i = 0; i < slides.length; i++) {
          slides[i].style.display = "none";
        }
        for (i = 0; i < dots.length; i++) {
          dots[i].className = dots[i].className.replace(" active", "");
        }
        slides[slideIndex - 1].style.display = "block";
        dots[slideIndex - 1].className += " active";
      }
    
    
    jQuery(document).ready(function($) {
    
    
      $('.gallery').slick({
        dots: true,
        slidesToShow: 3,
        slidesToScroll: 1,
        autoplay: true,
        autoplaySpeed: 2000,
        infinite: true,
        focusOnSelect: true
      });
    
    
      $('.gallery_responsive').slick({
        dots: true,
        slidesToShow: 1,
        slidesToScroll: 1,
        autoplay: true,
        autoplaySpeed: 2000,
        infinite: true,
        focusOnSelect: true
      });
    
    
    });
    Come potrai notare che ho inserito i tag di apertura e chiusura
    codice:
    jQuery(document).ready(function($) {
    e
    codice:
    });
    solo per una parte del codice.

    Si tratta in sostanza di script con funzioni separate, anche se stanno tutti nello stesso documento: (quello tra i tag jquery sopra citato) è deputato a gestire il "carosello" delle immagini in miniatura.
    Il resto del codice (la parte più corposa, fuori da tag) gestisce la gallery che si apre quando si clicca su una delle immagini.

    Forse (è un ricordo vago, ma potrebbe avere un fondamento di verità) quando ho creato il codice (grazie a ChatGPT, dato che io non so usare JS) lui ha usato jquery per la parte delle miniature e JS puro per la gallery.

    Ma prendi quest'ultima info con le pinze, potrebbe essere errata.

    Grazie come sempre per il supporto!
    Ultima modifica di ivanisevic82; 07-08-2023 a 17:49

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.