IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

scroller dans un élément bloc.


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut scroller dans un élément bloc.
    Bonjour,

    j'apprends le javascript je suis des tutoriels sur le scrolling avec du javascript.
    Mais je voulais adapter ce que j'ai pu comprendre ( encore un petit niveau ) pour faire du scrolling dans un block !
    Car tous les tutos que j'ai vus se font sur la page web : une barre de navigation et on clique pour scroller à l'endroit voulu.
    Donc on sort un window.scrollTo (x,y) et ça marche , mais je n'arrive pas à adapter (enfin, je pense que mon problème vient de là).

    Attention, la page est moche , mais ce n'est pas ce sur quoi je travaille en ce moment dans mon apprentissage ( il y aura un gros travail à faire là aussi !)

    voici mon HTML:
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="fiches.css">
        <title>fiche</title>
    </head>
    <body>
        <div class="wrap">
            <header>
                <h2 class="subcategory">catégorie</h2>
                <div class="title">
                    <h1>titre</h1>
                    <p class="definition">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Et ea nam beatae excepturi modi tempora molestiae 
                        sint rerum, voluptates commodi consequuntur facere sapiente nostrum vero deserunt molestias maxime ducimus explicabo?</p>
                </div>
                <h2 class="type">sous-catégorie</h2>
            </header>
                <div class="content">
                    <nav>
                        <ul>
                            <li><a href="#syntaxe">Syntaxe</a></li>
                            <li><a href="#exemples">Exemples</a></li>
                            <li><a href="#associations">Associations</a></li>
                            <li><a href="#liens">liens</a></li>
                            <li><a href="#illustrations">Illustrations</a></li>
                            <li><a href="#notes">notes</a></li>
                        </ul>
                    </nav>
                    <main class="display">
                        <section id="syntaxe"><h2>Syntaxe</h2></section>
                        <section id="exemples"><h2>Exemples</h2></section>
                        <section id="associations"><h2>Associations</h2></section>
                        <section id="liens"><h2>liens</h2></section>
                        <section id="illustrations"><h2>Illustrations</h2></section>
                        <section id="notes"><h2>Notes</h2></section>
                    </main>
                </div>
                <footer></footer>
        </div>
        <script src="lescroll.js"></script>
    </body>
    </html>

    puis mon CSS:
    Code CSS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    * {
        margin: 0px;
        padding: 0px;
        box-sizing: border-box;
    }
     
    body {
        height: 100vh;
        width: 100vw;
        display: flex;
        justify-content: center;
        align-items: center;
    }
     
    .wrap {
        height: 60%;
        width: 60%;
        display: flex;
        justify-content: center;
        flex-direction: column;
        border: 2px solid firebrick;
    }
     
    header {
        width: 100%;
        height: 30%;
        margin-left: 5px;
        display: flex;
        justify-content: space-between;
    }
     
    h1 {
        text-transform: uppercase;
    }
     
    .content {
        height: 70%;
        width: 100%;
        margin-left: 5px;
        display: flex;
    }
     
    .title {
        text-align: center;
        width: 60%;
        height: 100%;
    }
     
     
    main {
        border: 2px solid black;
        width: 80%;
        height: 100%;
        margin-left: 5px;
        margin-right: 5px;
        overflow: hidden;
        /*scroll-behavior: smooth;*/
    }
     
    nav {
        width: 20%;
        height: 100%;
    }
     
    ul {
        height: 100%;
        list-style-type: none;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }
     
    li {
        border: 2px solid red;
        text-align: center;
        height: 16%;
        line-height: 250%;;
    }
     
    section{
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        text-transform: uppercase;
    }
     
    section:nth-child(2n+1) {
        background-color: red;
    }
     
    a {
        display: block;
        width: 100%;
        height: 100%;
    }
     
    ul a:hover {
        background-color: #000;
        color: white;
    }
     
    .subcategory, .type {
        width: 20%;
        height: 100%;
        text-align: center;
        padding: 5% 0;
    }

    et enfin mon javascript:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    /* recupération des liens et association au click */
    const links = document.querySelectorAll('ul li a');
    console.log(links);
    for (const link of links) {
        link.addEventListener('click', move);
    };
     
    function move(event) {
        event.preventDefault();
        console.clear();
        console.group("le lien: ", this);
        /* récupération de la position de la cible du lien */
        const ref = this.getAttribute('href');
        console.log("nom dela cible:", ref);
        const target = document.querySelector('main').querySelector(ref);
        console.log("la cible: ", target);
        const targetPosition = target.getBoundingClientRect().top;
        console.log("position de la cible: ", targetPosition);
        /*  récupération de la distance à scroller: celle du main - celle de la cible */
        const finalposition = document.querySelector('main').getBoundingClientRect().top;
        console.log("position du main: ", finalposition);
        const distanceToScroll = targetPosition - finalposition;
        console.log("pixels à parcourrir: ", distanceToScroll);
        let start = null;
        const duration = 2000;
        window.requestAnimationFrame(scrolling);
        function scrolling(timestamp) {
            if (!start) {
                start = timestamp;
            }
            let progress = (timestamp - start);
            const step = distanceToScroll*(progress/duration);
            document.querySelector('main').scrollTo(0, step);
            if (progress<duration) {
                window.requestAnimationFrame(scrolling);
            }
        }
    }
    Le seul truc qui cloche: lorsque je clique sur un lien autre que syntaxe, ça m'affiche la section syntaxe au lieu de scroller !!!
    Et je dois cliquer encore une fois sur le même lien pour scroller , mais du coup les calculs qui se font en partant de la section à scroller sont faux et le scroll n'est pas bon !

    Alors voilà, pourquoi ça ne scrolle pas lorsque je clique sur un lien ? que se passe-t-il justement lorsque je clique ?

    Merci pour vos réponses

    Laurent.

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Bonjour,
    tu oublies d'ajouter la position du scroll de ton élément <main> au moment du clic pour connaître la position à atteindre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const elMain = document.querySelector('main');
    // ....
    const distanceToScroll = targetPosition - finalposition +elMain.scrollTop;

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    Bonjour,

    Ça fait quelque chose de mieux, mais c'est pas encore ça !
    Mais j'ai déjà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const finalposition = document.querySelector('main').getBoundingClientRect().top;
    Ça représente quoi ? Pour moi c'est la position du main ( le haut ) et cette position ne change jamais ! ( j'ai vérifié avec un console.log ) C'est bien là que je veux aller en scrollant !
    si je modifie le code comme tu le proposes, il affiche toujours la section syntaxe ( la première section ) puis scrolle jusqu'à l'élément demandé .
    Il ne reste plus qu'à le faire aller directement à l'élément demandé sans passer par la section syntaxe ... !

    Je comprends de moins en moins les positions

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Ça représente quoi ? Pour moi c'est la position du main ( le haut ) et cette position ne change jamais ! ( j'ai vérifié avec un console.log
    Sauf si la page scroll ! donc il importe de prendre les données sur le même bases/références.
    element.getBoundingClientRect.


    si je modifie le code comme tu le proposes, il affiche toujours la section syntaxe ( la première section ) puis scrolle jusqu'à l'élément demandé .
    C'est ton code qui le prévoit dans ta fonction scrolling, tu repars à chaque fois de 0.


    Il ne reste plus qu'à le faire aller directement à l'élément demandé sans passer par la section syntaxe ... !
    Il te faut changer d'approche et calculer le chemin à faire qui sera soit positif soit négatif.

    Je te propose ce code à étudier et à améliorer le cas échéants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function anim(e) {
        e.preventDefault();
        const elMain = document.querySelector('main');
        const elMainTop = elMain.getBoundingClientRect().top;
        const elMainScrollTop = elMain.scrollTop;
     
        const ref = this.getAttribute('href');
        const elTarget = elMain.querySelector(ref);
        const elTargetTop = elTarget.getBoundingClientRect().top + elMainScrollTop;
     
        const deltaScroll = elTargetTop - elMainScrollTop - elMainTop;
     
        let start = null;
        const duration = 2000;
     
        function scrolling(timestamp) {
            if (!start) {
                start = timestamp;
            }
            const progress = (timestamp - start);
            const pourCent = (progress / duration);
            const posScroll = elMainScrollTop + (deltaScroll * pourCent);
            elMain.scrollTo(0, posScroll);
            if (progress < duration) {
                window.requestAnimationFrame(scrolling);
            }
        }
        window.requestAnimationFrame(scrolling);
    }
    C'est pas commenté mais cela me semble suffisamment clair, la fonction n'a pas le même nom, tu peux donc faire cohabiter les deux dans ta page pour test.

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    ÇA Y EST , J'AI COMPRIS, MON PROBLÈME SE SITUAIT LÀ:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const step = distanceToScroll*(progress/duration);
    document.querySelector('main').scrollTo(0, step);
    Car je n'avait pas lu ce lien
    ( Très bien javascript.infos !!! )

    Du coup il suffit juste de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const step = mainScrollTop + (distanceToScroll*(progress/duration));
    avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const mainScrollTop = document.querySelector('main').scrollTop;
    et du coup ça va mieux ...
    Je n'avais pas compris comment fonctionnait le scrollTop !

    Merci pour ton aide.
    Je vais m'attaquer maintenant à faire un scroll plus linéaire ! Avec des interpolations linéaires ( évidemment ) parce que j'ai vu ça dans des tutoriels en vidéo. Ça vaut le coup ou pas ?
    Plus précisément dans quelles conditions l'interpolation va servir ?

    Laurent.

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    et du coup ça va mieux ...
    Je n'avais pas compris comment fonctionnait le scrollTop !
    Voilà donc qui est fait


    Je vais m'attaquer maintenant à faire un scroll plus linéaire ! Avec des interpolations linéaires ( évidemment ) parce que j'ai vu ça dans des tutoriels en vidéo. Ça vaut le coup ou pas ?
    Plus précisément dans quelles conditions l'interpolation va servir ?
    Le principal soucis qu'il y a avec le « défilement automatique » outre que c'est très souvent chiant et soulant, c'est le choix de la vitesse.

    Dans ton cas tu réalises un défilement en 2s que tu scrolles 200px ou 3000px ce qui tu l’avoueras n'est pas super agréable visuellement !

    Perso je trouve préférable de fixer une vitesse de défilement comme par exemple en déclarant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // speed : 1s pour 2000px
    const speed = 1000 / 2000;
    const duration = speed * Math.abs(distanceToScroll);
    tu auras de la sorte quelque chose de plus homogène.

    Concernant les effets de défilement, je te conseille de regarder du côté de : Easing Functions Cheat Sheet.
    La mise en oeuvre est des plus simple, tu passes le pourcentage d'avancement à la fonction et elle te retourne celui à appliquer pour obtenir ton effet.

    En reprenant, plus ou moins, le code vu cela donnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const progress = (timestamp - start);
    const pourCent = easeInOutCubic(progress / duration);
    const posScroll = elMainScrollTop + (distanceToScroll * pourCent);
    elMain.scrollTop = posScroll;
    avec la déclaration de la fonction easeInOutCubic suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function easeInOutCubic(x) {
      return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
    }
    Après les goûts et les couleurs ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. exceptions plsql dans les sous blocs
    Par r83 dans le forum PL/SQL
    Réponses: 3
    Dernier message: 02/04/2007, 23h33
  2. [CSS] Image de fond dans un élément <div>
    Par Yogui dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 16/05/2006, 13h05
  3. [XML] attribut dans l'élément racine
    Par gabychon dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 27/04/2006, 14h44
  4. Limiter la saisie dans un élément texte
    Par manou.K dans le forum Oracle
    Réponses: 2
    Dernier message: 28/07/2005, 11h41
  5. comment scroller dans un div avec l'evenement onmousemove.
    Par julien.v dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 13/06/2005, 16h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo