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 :

Sticky Header - Tremblement lors de modification au scroll via javascript


Sujet :

JavaScript

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2019
    Messages : 2
    Par défaut Sticky Header - Tremblement lors de modification au scroll via javascript
    Bonjour,

    Je butte depuis deux jours sur un problème de changement de la mise en forme de mon header au scroll via Javascript, et après avoir fouillé sur tous les sites que je connais, je suis à court d'idée. Je ne suis pas très habitué de ce genre de demande sur forum, j'ai fouillé les autres sujets sans succès, j'ai lu les règles, mais s'il manque des informations ou qu'il y a déjà un sujet existant à côté duquel je suis passé, n'hésitez pas à me les demander ou à me rediriger.

    Je travaille sur un site sur lequel je dois modifier la mise en forme du header au scroll. Je fais ça en javascript en vérifiant la distance avec le haut de l'écran et en ciblant les différents éléments à modifier avec querySelector. Si je suis au delà de 50px du haut du document, alors la mise en forme est appliquée, sinon, on revient à la mise en forme d'origine.

    PROBLÈME : au scroll, dans la zone de changement du style du header, le site "tremble" car oscille rapidement entre les deux styles en continu rendant la transition insupportable.

    Le site pour mieux visualiser : https://maule.synapseweb.fr/

    Je suis passé par trois versions de cette condition JS avec le même souci. Le code actuel (la condition) est récupéré d'un site avec le même besoin mais moins de mise en forme dans lequel cela fonctionnait (http://albret.synapseweb.fr)

    Est-ce que quelqu'un aurait une piste ? Merci d'avance ! (script utilisé en dessous)

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
     
    <script>
     
     
    window.onscroll = function() {scrollFunction()};
     
    function scrollFunction() {
    if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
     
    document.querySelector('.blocMenuDemarche').style. zIndex='3';
     
    document.querySelector('.modLogoTitreTop h1 a').style.color='#000';
    document.querySelector('.modLogoTitreTop h1 a strong').style.color='#000';
     
    document.querySelector('.blocMenuDemarche').style. marginTop='-112px';
     
    document.querySelector('.headerPartAbsolute').styl e.textAlign='left';
     
    document.querySelector('.modLogoTitreTop h1 strong').style.fontSize='34px';
    document.querySelector('.modLogoTitreTop h1 strong').style.lineHeight='2px';
     
    document.querySelector('.modLogoTitreTop h1').style.fontSize='18px';
    document.querySelector('.modLogoTitreTop h1').style.lineHeight='16px';
     
    document.querySelector('.modLogoTitreTop img').style.marginTop='4px';
    document.querySelector('.modLogoTitreTop img').style.height='50px';
     
    document.querySelector('.overlayShadowTop').style. backgroundColor='#FFF';
     
     
    document.querySelector('.bgColorMainMenu').style.m arginTop='-8px';
     
     
    } else {
     
    document.querySelector('.blocMenuDemarche').style. zIndex='2';
    document.querySelector('.blocMenuDemarche').style. marginTop='0px';
     
    document.querySelector('.headerPartAbsolute').styl e.textAlign='center';
     
    document.querySelector('.modLogoTitreTop h1 strong').style.fontSize='106px';
    document.querySelector('.modLogoTitreTop h1 strong').style.lineHeight='51px';
     
    document.querySelector('.modLogoTitreTop h1').style.fontSize='48px';
    document.querySelector('.modLogoTitreTop h1').style.lineHeight='51px';
     
    document.querySelector('.modLogoTitreTop img').style.marginTop='21px';
    document.querySelector('.modLogoTitreTop img').style.height='auto';
     
    document.querySelector('.overlayShadowTop').style. backgroundColor='rgba(0, 0, 0, 0.5)';
     
    document.querySelector('.modLogoTitreTop h1 a').style.color='#FFF';
    document.querySelector('.modLogoTitreTop h1 a strong').style.color='#FFF';
     
    document.querySelector('.bgColorMainMenu').style.m arginTop='0px';
     
    }
    }
     
    </script>

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Houlà, oui ! Il ne faut pas être épileptique !

    1- Déjà, pour commencer, ce n'est pas une bonne idée de modifier les styles CSS comme ça.
    (d'autant que tu as des espaces en trop : style. marginTop / .styl e.textAlign / ...)


    2- Une meilleure idée est d'ajouter/supprimer une classe CSS à l'élément englobant (ici, j'ai choisi "body", mais ça peut être ".overlayShadowTop") :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    window.onscroll = function() {scrollFunction()};
     
    function scrollFunction()
    {
      if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
        document.querySelector('body').classList.add('navIsMini'); // (menu réduit)
      } else {
        document.querySelector('body').classList.remove('navIsMini'); // (menu "normal", maxi)
      }
    }
    Ensuite, on applique les styles dans la feuille de style CSS.

    3- Enfin, pour le tremblement, remplace (dans template.css, ligne 8266) :
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    .overlayShadowTop {
        background-color: rgba(0,0,0,0.5);
        position: sticky;
    ...
    par
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    .overlayShadowTop {
        background-color: rgba(0,0,0,0.5);
        position: fixed;
    ...
    Il me semble que ça devrait régler le problème.


    4- [EDIT] J'ai remarqué que le header n'est pas correctement "responsive".
    Il faut remplacer (dans template.css, ligne 8301) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    .headerPartAbsolute {
        width: 1100px;
    ...
    par
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    .headerPartAbsolute {
        max-width: 1100px;
    ...
    Il faudra aussi faire d'autres adaptations pour mobile...
    Dernière modification par NoSmoking ; 24/06/2019 à 10h21.

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2019
    Messages : 2
    Par défaut
    Merci beaucoup pour tes retours jreaux62 ! Je réponds en reprenant ta numérotation pour plus de lisibilité.

    1) Je prends note pour la bonne pratique (cf point 2). Les espaces se sont rajouté lors d'un copié/collé probablement mal effectué de ma part, ils n'étaient apparemment pas dans le script d'origine. Je serai plus attentif la prochaine fois.

    2) J'ai modifié les scripts hoverMenu (qui met une couche grisée sur le reste du site au survol menu) et le fameux script pour le sticky menu, en ajoutant une classe et la retirant sur overlayShadowTop (pour le sticky, la classe est "stickyScrolled".

    Maintenant, cela donne ça (pour le sticky menu en tout cas) :

    Script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    		window.onscroll = function() {scrollFunction()};
     
    		function scrollFunction() {
    		  if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
    			document.getElementsByClassName('overlayShadowTop')[0].classList.add('stickyScrolled');
    		  } else {
    			document.getElementsByClassName('overlayShadowTop')[0].classList.remove('stickyScrolled');
    		  }
    		}
    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
    .overlayShadowTop.stickyScrolled{
    	background-color:#FFF;
    }
     
    .overlayShadowTop.changesOnHoverMenu.stickyScrolled{
    	background-color:#FFF;
    }
     
    .stickyScrolled .blocMenuDemarche{
    	z-index:3;
    	margin-top:-112px;
    }
     
    .stickyScrolled .modLogoTitreTop h1 a{
    	color:#000;
    }
     
    .stickyScrolled .modLogoTitreTop h1 a strong{
    	color:#000;
    }
     
     
    .stickyScrolled .headerPartAbsolute{
    	text-align:left;
    }
     
     
    .stickyScrolled .modLogoTitreTop h1 strong{
    	font-size:34px;
    	line-height:2px;
    }
     
     
    .stickyScrolled .modLogoTitreTop h1{
    	font-size:18px;
    	line-height:16px;
    }
     
     
    .stickyScrolled .modLogoTitreTop img{
    	margin-top:4px;
    	height:50px;
    }
     
    .stickyScrolled .bgColorMainMenu{
    	margin-top:-8px;
    }

    3) Oh mon dieu ! Ça marche ! C'était si stupide ! Et je ne comprends même pas pourquoi j'avais le tremblement en sticky du coup... je vais regarder la doc de la position mieux pour comprendre le fonctionnement qui a entrainé ça ! Merci beaucoup !

    4) Pour le responsive, je compte le faire après le réglage de ce problème à coup de media-queries, morceau par morceau, donc normalement les tailles fixes ne devraient pas poser de souci vu qu'elles seront re-définies aux lignes de ruptures. Ton conseil d'ajouter une classe va d'ailleurs grandement me faciliter la tâche car m'évitera de jouer sur des "!important" partout pour dépasser le style inline. Encore merci !

  4. #4
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    Alors oui ça marche avec fixed au lieu de sticky, mais l'animation est moins complète qu'avant :
    Avec sticky, ce qui était sous l'entête se déplaçait progressivement durant l'animation (ça suivait le bouton "Démarches"), ce qui était du plus bel effet.

    Par contre, ce déplacement de la page s'accompagne d'une modification de la hauteur et de la position de la page : la barre de défilement s'adapte en fonction et le scrollTop repasse sous les 50 pixels, d'où le tremblement.
    On peut tenter un ajustement de la hauteur et de la position de la barre, mais si l'utilisateur déplace en plus la barre, il est difficile de savoir si c'est l'animation ou l'action de l'utilisateur qui affecte la position (on ne peut pas distinguer les deux par script, à moins peut-être d'examiner la position de la souris, mais ce serait trop compliqué).

    Pour conserver sticky et cette animation, il faudrait selon moi programmer soi-même l'animation avec un setInterval appelant une fonction qui : 1) Mémorise la position et la hauteur de la page, 2) modifie les propriétés css en fonction du temps écoulé, 3) réajuste la position et la hauteur de la page (peut-être en faisant varier une sorte de marge en haut) pour que la position de la barre de défilement reste inchangée.
    C'est la théorie, reste à voir ce que ça donnerait en pratique...

    Si fixed convient, alors tant mieux, car c'est beaucoup plus simple à gérer.

    Sinon, il y aurait une optimisation à faire : une fois que scrollTop dépasse 50 pixels, pas besoin de ré-exécuter en permanence la changement de style quand on défile la page. De même, quand on repasse sous les 50 pixels.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,


    absolute / fixed
    "...L'élément est retiré du flux normal et aucun espace n'est laissé pour l'élément...."

    sticky
    La position de la boîte est calculée en fonction du flux normal du document.
    Ensuite, la boîte est décalée par rapport à son ancêtre de défilement le plus proche....
    C'est l'explication donnée par Loralina :
    Citation Envoyé par Loralina Voir le message
    ...[en position sticky],
    ...ce déplacement de la page s'accompagne d'une modification de la hauteur et de la position de la page : la barre de défilement s'adapte en fonction et le scrollTop repasse sous les 50 pixels, d'où le tremblement....
    En position absolute ou fixed, pas de décalage puisque l'élément (retiré du flux) n'est pas pris en compte par le scrollTop.

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

Discussions similaires

  1. Rendre le header static lors du scroll
    Par doubleface2 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 11/07/2016, 20h04
  2. [Tomcat - Datasource] Pb lors de modification de jsp
    Par babylone7 dans le forum Tomcat et TomEE
    Réponses: 8
    Dernier message: 06/06/2006, 17h38
  3. [ImageMagick] Header envoyé lors de la création d'une image
    Par KLiFF dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 25/10/2005, 16h35
  4. Afficher une dropdownlist lors de modif dans une DataGrid
    Par MiJack dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/11/2004, 17h42
  5. Erreur lors de modification d'une table
    Par seb.49 dans le forum SQL
    Réponses: 11
    Dernier message: 13/01/2003, 17h16

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