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

    Script Sezione espandibile Ho perso l'effetto di transizione, dove ho sbagliato?

    Ciao ragazzi, ho bisogno di un vostro parere per sistemare questo script, che ha la funzione di inserire un contenuto espandibile (effetto collapse) in una pagina web.

    Lo script originale e' il seguente: LINK , funziona benissimo con contenuto STATICO.

    modificando leggermente lo script pero' sono riuscito a fare in modo che la sezione si Espandesse o rimpicciolisse in automatico, in base al suo contenuto, ecco il codice con il pezzo da me modificato:

    codice:
    <script>
    // Original JavaScript code by Chirp Internet: chirpinternet.eu  // Please acknowledge use of this code by including this header.
    
    
    window.addEventListener("DOMContentLoaded", e => {
    
    
      const getContainerHeight = el => {
        return window.getComputedStyle(el).getPropertyValue("height");
      };
    
    
      const setTransitionHeights = el => {
    
    
        let containerWasOpen = el.classList.contains("open");
    
    
        el.style.height = null;
    
    
        el.classList.remove("open", "ready");
        el.dataset.initial = getContainerHeight(el);
    
    
        el.classList.add("open");
        el.dataset.final = getContainerHeight(el);
        el.classList.remove("open");
    
    
        if(containerWasOpen) {
          el.classList.add("open");
          el.style.height = el.dataset.final;
        } else {
          el.style.height = el.dataset.initial;
        }
    
    
        el.classList.add("ready");
    
    
      };
    
    
      document.querySelectorAll(".collapsible.slow").forEach(current => {
    
    
        let toggler = document.createElement("div");
        toggler.className = "toggler";
        current.appendChild(toggler);
    
    
        setTransitionHeights(current);
    
    
        toggler.addEventListener("click", e => {
          current.style.height = current.classList.toggle("open") ? current.dataset.final : current.dataset.initial;
        });
    
    
      });
    document.querySelectorAll(".collapsible.slow").forEach(l=> { //PEZZO MODIFICATO
      l.addEventListener("click", e => {  //ALTRO PEZZO MODIFICATO
    
    
        document.querySelectorAll(".collapsible.slow").forEach(current => {
          setTransitionHeights(current);
        });
    
    
      });
    })
    
    
    });
    
    
    </script>
    Lo script FUNZIONA, il problema e' che cosi facendo, ho perso l'effetto di transizione ottenuto grazie al seguente codice CSS:
    codice:
      .collapsible.slow {
        position: relative;
        overflow: hidden;
        padding-bottom: 0.5em;
        transition: height 0.5s ease-out;
      }
    Potete vedere il risultato di questa modifica al codice QUI: LINK
    Mentre questa e' la versione con il codice originale (effetto di transizione c'e' ma la sezione non si auto espande/comprime con il contenuto: LINK

    Qualcuno mi saprebbe indicare se ho sbagliato qualcosa, o se c'e' qualche modo per mantenere l'effetto di transizione e allo stesso modo far si che la sezione si espande/comprime in base al suo contenuto.

    A disposizione per ulteriori chiarimenti, vi sarei davvero grato se mi aiutate.

  2. #2
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Ciao, la logica che hai usato non può andare bene.

    La questione non è così semplice da comprendere ma grossomodo ti spiego cosa avviene e come puoi risolvere.

    L'applicazione dei gestori click eseguita in quel modo comporta un primo fattore che causa il problema: il cosiddetto "bubbling" nella propagazione degli eventi. Normalmente la propagazione degli eventi avviene dall'elemento più interno a quello più esterno.

    Ulteriore premessa:


    Da quel che ho potuto valutare, la funzione setTransitionHeights() serve solo a reimpostare le altezze limiti e l'altezza corrente, in base allo stato (aperto/chiuso) in cui si trova l'elemento. Richiamando tale funzione l'altezza corrente sarà impostata istantaneamente senza eseguire alcuna transizione; questo perché all'interno della funzione si gioca con la classe "open" per determinare lo stato aperto/chiuso dei contenitori e poterne rilevare i valori limiti. In sostanza, per via di tali operazioni, la transizione viene bypassata.

    La transizione invece avviene applicando/rimuovendo la classe "open" e impostando height secondo il corrispettivo valore limite. Esattamente ciò che avviene al click dei "toggler".



    Considerando questa premessa, il tuo script aggiuntivo applica un gestore di evento click a tutti i contenitori espandibili e, in tale gestore, vai a inizializzare nuovamente le altezze, ad ogni click, per tutti i contenitori espandibili richiamando appunto la funzione anzidetta.

    Questo gestore, dal momento che fa riferimento al contenitore, viene eseguito (per la questione del bubbling) dopo quello impostato per il "toggler" che invece sta dentro il contenitore. Per tale motivo, l'azione del "toggler" viene praticamente inibita dalla funzione setTransitionHeights(), per cui l'altezza è reimpostata istantaneamente senza alcuna transizione.

    La stessa cosa avviene per l'evento "resize" dove viene richiamata la funzione che inizializza i limiti e imposta direttamente l'altezza senza che avvenga però alcuna transizione. Cioè, se si restringe la pagina (vedi quanto indicato nella pagina dello script), i contenitori "collapsible" (nel variare la loro larghezza) variano anche in altezza; per tale motivo è stato impostato l'evento resize in cui viene richiamata quella funzione.

    Certo, restringendo manualmente la finestra del browser, sembra quasi che avvenga una transizione, invece viene semplicemente reimpostata l'altezza dei contenitori (puoi provare nella pagina dello script, dove i testi contenuti riempiono l'intera larghezza dei contenitori).

    Ora, a parte far funzionare la transizione al click sui "toggler", non mi è chiaro se tu vuoi che avvenga la transizione anche quando vai ad espandere i tuoi contenuti - perché in tal caso ci sarebbero appunto da valutare ulteriori fattori - o se ti è sufficiente che il contenitore si ridimensioni istantaneamente così come avviene per l'evento "resize".

    Ad ogni modo, più che eseguire l'operazione in modo ridondante sull'evento click per tutti i contenitori - dove stai quindi richiamando la funzione a prescindere che avvenga un effettiva variazione delle dimensioni - potresti piuttosto eseguirla al click dei tuoi elenchi espandibili, perché è in quell'istante che la dimensione va a cambiare.

    Ti propongo qui una possibile soluzione dove ho previsto la transizione anche al toggle sugli elenchi; ho accorpato l'intero script dentro il gestore principale, per cui se lo provi sulla tua pagina dovrai rimuovere lo script che hai posto a fine body per il toggle degli elenchi:

    codice:
    window.addEventListener("DOMContentLoaded", e => {
      // Original JavaScript code by Chirp Internet: chirpinternet.eu
      // Please acknowledge use of this code by including this header.
    
      const getContainerHeight = el => {
        return window.getComputedStyle(el).getPropertyValue("height");
      };
    
      const setTransitionHeights = el => {
    
        let containerWasOpen = el.classList.contains("open");
    
        el.style.height = null;
    
        el.classList.remove("open", "ready");
        el.dataset.initial = getContainerHeight(el);
    
        el.classList.add("open");
        el.dataset.final = getContainerHeight(el);
        el.classList.remove("open");
    
        if (containerWasOpen) {
          el.classList.add("open");
          el.style.height = el.dataset.final;
        } else {
          el.style.height = el.dataset.initial;
        }
    
        el.classList.add("ready");
    
      };
    
      document.querySelectorAll(".collapsible.slow").forEach(current => {
    
        let toggler = document.createElement("div");
        toggler.className = "toggler";
        current.appendChild(toggler);
    
        setTransitionHeights(current);
    
        toggler.addEventListener("click", e => {
          current.style.height = current.classList.toggle("open") ? current.dataset.final : current.dataset.initial;
        });
    
      });
    
      window.addEventListener("resize", e => {
    
        document.querySelectorAll(".collapsible.slow").forEach(current => {
          setTransitionHeights(current);
        });
    
      });
    
      var toggler = document.getElementsByClassName("caret");
      var i;
    
      for (i = 0; i < toggler.length; i++) {
        toggler[i].addEventListener("click", function() {
          this.parentElement.querySelector(".nested").classList.toggle("active");
          this.classList.toggle("caret-down");
    
          // Qui reimposto le altezze del contenitore corrente ed eseguo la transizione
          
          const collapsible = this.closest('.collapsible.slow');
          const curHeight = getContainerHeight(collapsible);
          setTransitionHeights(collapsible);
          collapsible.style.height = curHeight;
          setTimeout(() => {
            collapsible.style.height = collapsible.dataset.final
          }, 0)
    
        });
      }
    });



    PS: occhio anche agli errori di validazione del markup HTML e del CSS, presenti sulle tue pagine. Se passi le pagine che hai linkato ad un validatore, tira fuori diversi errori. Consiglio eventualmente di correggerli.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  3. #3
    Ciao, grazie mille, mi hai chiarito molto meglio le idee, avevo la necessità che la transizione si avviasse sempre proprio come avviene nello script che hai modificato. Ora mi è molto più chiaro perchè la mia modifica non era sufficiente! Sto riprendendo a programmare dopo un pò di anni in cui sono stato fermo e credo che mi sarà molto utile anche il validatore per fare un pò di pulizia Grazie ancora, erano un pò di giorni che ci sbattevo la testa senza trovare soluzione

    Ps: Non so perchè ma nonostante ho provato a risponderti facendo Rispondi Quotando, non mi vuole proprio riportare il tuo messaggio (dovrei fare il Quote manualmente)

  4. #4
    Un ultima cosa, secondo te è possibile inserire un effetto di transizione simile anche per lo script incorporato quando si clicca su una voce ad es. Thomistic?, le voci spuntano all'improvviso, invece se riesco ad inserire un effetto transizione o graduale anche li, sarebbe ottimo. In ogni caso sei stato già gentilissimo!


    CSS dello script:
    codice:
    ul, #myUL {  list-style-type: none;
    }
    
    
    #myUL {
      margin: 0;
      padding: 0;
    }
    
    
    .caret {
      cursor: pointer;
      -webkit-user-select: none; /* Safari 3.1+ */
      -moz-user-select: none; /* Firefox 2+ */
      -ms-user-select: none; /* IE 10+ */
      user-select: none;
    }
    
    
    .caret::before {
      content: "\25B6";
      color: black;
      display: inline-block;
      margin-right: 6px;
    }
    
    
    .caret-down::before {
      -ms-transform: rotate(90deg); /* IE 9 */
      -webkit-transform: rotate(90deg); /* Safari */'
      transform: rotate(90deg);  
    }
    
    
    .nested {
      display: none;
    }
    
    
    .active {
      display: block;
    }

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Ciao, grazie mille, mi hai chiarito molto meglio le idee
    [...]
    Sto riprendendo a programmare dopo un pò di anni in cui sono stato fermo e credo che mi sarà molto utile anche il validatore per fare un pò di pulizia
    ottimo! buona ripresa allora


    Ps: Non so perchè ma nonostante ho provato a risponderti facendo Rispondi Quotando, non mi vuole proprio riportare il tuo messaggio (dovrei fare il Quote manualmente)
    Purtroppo dipende dalla ruggine, sempre più spessa, di questa piattaforma e dal cloudflare a cui si appoggia, dove il firewell blocca i messaggi una volta su due, specialmente quando c'è di mezzo del codice.

    Ho faticato anche io nel pubblicare quel messaggio

    Ad ogni modo, dal momento che i post nelle discussioni hanno normalmente una disposizione lineare di lettura, nessun problema se non quoti per intero. Anzi, personalmente ho sempre preferito che non mi si quoti per intero; non trovo alcun motivo di riportare in blocco interi messaggi se la lettura è comunque lineare, la renderebbe inutilmente "sporca".

    Per me va bene così.

    Buon proseguimento e un felice weekend


    EDIT: ho visto ora il tuo ultimo post, gli do uno sguardo e ti rispondo più tardi.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    ottimo! buona ripresa allora
    Grazie, grazie a questo grattacapo dello script e alle prime sfide mi sto già riappassionando


    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    Purtroppo dipende dalla ruggine, sempre più spessa, di questa piattaforma e dal cloudflare a cui si appoggia, dove il firewell blocca i messaggi una volta su due, specialmente quando c'è di mezzo del codice.

    Ho faticato anche io nel pubblicare quel messaggio

    Ad ogni modo, dal momento che i post nelle discussioni hanno normalmente una disposizione lineare di lettura, nessun problema se non quoti per intero. Anzi, personalmente ho sempre preferito che non mi si quoti per intero; non trovo alcun motivo di riportare in blocco interi messaggi se la lettura è comunque lineare, la renderebbe inutilmente "sporca".

    Per me va bene così.

    Buon proseguimento e un felice weekend


    EDIT: ho visto ora il tuo ultimo post, gli do uno sguardo e ti rispondo più tardi.
    Si effettivamente non ho avuto problema a citarti adesso che non c'era codice da riportare, significa che citerò un pezzo alla volta! Comunque ti ringrazio, guardalo pure quando sei libero, nel frattempo auguro anche a te un buon weekend!

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    Ciao, non ho avuto tempo di dedicarmi ad elaborare qualcosa ma ti do giusto qualche info al volo.

    Se vuoi avere un effetto transizione anche per quelle liste, teoricamente sarebbe pensabile usare lo stesso sistema opportunamente impostato anche per tali elementi. La cosa però potrebbe risultare più complicata del previsto perché andrebbero gestiti diversi fattori, come il calcolo delle altezze che possono variare in modi imprevedibili dal momento che hai più parti annidate che possono ridimensionarsi all'interno dello stesso contenuto.

    Fosse per me userei un sistema differente che potrebbe essere applicato forse più facilmente su più elementi anche annidati.
    La tecnica è quella di lavorare sulla proprietà max-height, anziché height.

    Trovi degli esempi su w3schools: How TO - Collapse

    Chiaramente andrebbe impostata la struttura HTML in modo opportuno.
    Per il momento è giusto un'idea, bisogna capire poi se e come possa essere adoperata nel tuo specifico caso.

    Magari fai tu stesso qualche prova; nel caso, posso provare qualcosa anche io appena posso.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  8. #8
    Quote Originariamente inviata da KillerWorm Visualizza il messaggio
    Ciao, non ho avuto tempo di dedicarmi ad elaborare qualcosa ma ti do giusto qualche info al volo.

    Se vuoi avere un effetto transizione anche per quelle liste, teoricamente sarebbe pensabile usare lo stesso sistema opportunamente impostato anche per tali elementi. La cosa però potrebbe risultare più complicata del previsto perché andrebbero gestiti diversi fattori, come il calcolo delle altezze che possono variare in modi imprevedibili dal momento che hai più parti annidate che possono ridimensionarsi all'interno dello stesso contenuto.

    Fosse per me userei un sistema differente che potrebbe essere applicato forse più facilmente su più elementi anche annidati.
    La tecnica è quella di lavorare sulla proprietà max-height, anziché height.

    Trovi degli esempi su w3schools: How TO - Collapse

    Chiaramente andrebbe impostata la struttura HTML in modo opportuno.
    Per il momento è giusto un'idea, bisogna capire poi se e come possa essere adoperata nel tuo specifico caso.

    Magari fai tu stesso qualche prova; nel caso, posso provare qualcosa anche io appena posso.
    Ciao KillerWorm, guarda sei stato già gentilissimo avendomi risolto il problema principale che era inserire l'auto collapse senza perdere la transizione, questa è solo una chicca per perfezionare ulteriormente il contenuto, ma non è una cosa fondamentale, quindi magari mi ci dedicherò con calma, approfondendo il discorso su w3schools. Nel frattempo ti ringrazio per il supporto che mi hai già dato!

  9. #9
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,771
    bene allora, per il momento lasciamo così, se poi hai ancora bisogno fai sapere

    Buona domenica
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

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.