Skrollr - how to permit the scroll of a long text of unknown size until the end

57 views Asked by At

Please what is the trick so that a long text of several pages (filled for example with text "Lorem ipsum ...") of unknown length (no known in advance) become visible beyond one page which is freezes (not able to see after) because skrollr ?

My simple skrollr code that bug to scrool to the end of a long text (size not fixed) beyond one page:

<div id = "corpsDiv" 
    data-0 = "transform: translateY (100vh)" 
    data-500 = "transform: translateY (100vh)" 
    data-900 = "transform: translateY (0vh)">
        Lorem ipsum dolor sit amet. <BR> 
        Qui cupiditate nisi est praesentium omnis et reprehenderit veniam <BR>
        Est dolor perspiciatis ea placeat quaerat <BR> 
        et galisum provident aut cumque iste sed reiciendis esse <BR>
        ... etc <BR> 
</div>
1

There are 1 answers

0
Eric On

As no one answered, I share with you the solution that I found to help others :

<script type="text/javascript">
/* function : recalculSkrollr() 
=== Création dynamique du dernier attribut skrollr positionnant la fin du div de texte Corps de page pour pouvoir la scroller
Nota :  comme le div de texte ci-dessus "corpsDiv" est dynamique (ie de hauteur inconnue à l'avance selon le contenu et la taille d'écran), 
        et que skrollr ne sait donc pas afficher toute sa hauteur (ne connaissant pas sa valeur non figée no plus arbitrairement par le css),
        alors seule la première page de ce div de texte (positionné à 0vh par skrollr via data-0) sera visible,
        sans pouvoir la scroller tant qu'un attribut skrollr, indiquant jusqu'où scroller, ne sera pas créé pour voir l'intégralité de ce div, 
        soit tant qu'un attribut skrollr data-{hauteur_px_du_div} indiquant une valeur égale de translation Y négative (vers le haut) 
        de {hauteur_vh_du_div} (vh pour être homogène avec les autres unités vh des data skrollr du div) ne sera pas dynamiquement créé, 
        ce qui est fait (nécessairement après ce div) ici à la fin de cette page.
    */
function recalculSkrollr() {
    // Calcul du viewport height en cours (via la taille de l'écran)
    screenHeight= window.innerHeight || (document.body && document.body.clientHeight) || 800;
    viewHeight = screenHeight / 100; // View port (1% de la hauteur d'écran)
    // Calcul hauteur du div en px (taille du div inconnue à l'avance) afin de pouvoir le scroller (ici scrollTop=0 car div par encore au-dessus du top à 0)
    vcorpsDiv = document.getElementById('corpsDiv');
    hauteurPxCorpsDiv = vcorpsDiv.offsetHeight;
    // Garder une hauteur minimum (150 vh) pour afficher correctement un corpsDiv qui serait trop petit (skrollr perturbé sinon)
    hauteurPxCorpsDiv = Math.max(hauteurPxCorpsDiv , 150 * viewHeight);
    // Calcul hauteur du div (en vh) pour permettre à skrollr de translater le div vers le haut
    hauteurVhCorpsDiv = Math.trunc(hauteurPxCorpsDiv / viewHeight);
    // Calcul du décalage du div (en vh) vers le haut une fois entièrement scrollé (en soustrayant l'offset déjà appliqué dans la déclaration html du corpsDiv via son attribut skrollr data-0="transform:translateY(100vh)")
    offsetVhCorpsDiv = 100; 
    decaleVhCorpsDiv = hauteurVhCorpsDiv - offsetVhCorpsDiv;
    // Calcul de l'attribut skrollr (libellé et valeur du tag) à créer dynamiquement afin de pouvoir scroller entièrement le div
    csstag='data-'+hauteurPxCorpsDiv;
    cssvalue='transform:translateY(-'+decaleVhCorpsDiv+'vh)'; // pas besoin à priori des accolades css : cssvalue = '{' + cssvalue + '}'
    // Création de l'attibut skrollr permettant de scroller le div jusqu'au bout
    document.getElementById('corpsDiv').setAttribute(csstag, cssvalue);
    // Création de l'attibut height du div
    cssheight = hauteurVhCorpsDiv + 'vh';
    document.getElementById('corpsDiv').style.height = cssheight;
    }

recalculSkrollr();

// Décaler dans le temps (500ms) l'init du scroll pour laisser le temps à la page de se charger (sinon le scrollr.menu avec une url #xxx restera en haut)
setTimeout(function() {
  /* ==== Initialisation du gestionnaire skrollr (voir source et doc https://prinzhorn.github.io/skrollr/ ) */
  var skroller = skrollr.init({
        constants: {
            // Position vertical avant et après l'ouverture du portail (en px) pour l'animer dans l'image d'entete
            avantportail: function() {
                // Calcul d'une constante dynamique (possible aussi d'accéder à l'instance skrollr avec `this` par ex. `this.relativeToAbsolute`)
                positionVhCible = 50; // position cible à atteindre en unité vh (1/100 du viewport height)
                positionPxCible = positionVhCible * viewHeight;
                return positionPxCible;
                },
            apresportail: function() {
                positionVhCible = 140; // position cible à atteindre en vh
                positionPxCible = positionVhCible * viewHeight;
                return positionPxCible;
                }
        }
  });

  //The options (second parameter) are all optional. The values shown are the default values.
  skrollr.menu.init(skroller, {
        //skrollr will smoothly animate to the new position using `animateTo`.
        animate: true,
        //The easing function to use.
        easing: 'sqrt',
        //Multiply your data-[offset] values so they match those set in skrollr.init
        scale: 1,
        //This event is triggered right before we jump/animate to a new hash.
        change: function(newHash, newTopPosition) {
            //console.log(hash, top);
        }
  });
}, 500);

// Recharger la page si la page change de taille afin de recalculer les attributs dynamiques de skrollr
function pageResize() { 
    document.location.reload();
    }
window.onresize = pageResize;
</script>