11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Ceci est mon premier message sur AlsaCréations que je lis depuis des années, mais cette fois ci je n'arrive pas de trouver de solution efficace à mon problème, j'ai donc décider de m'inscrire pour trouver un peu d'aide =)

Je vais donc commencer par me présenter rapidement, je m'appelle Alexandre, j'ai 29 ans et je suis développeur Web depuis 4-5 ans sur Perpignan et alentours. Je suis spécialisé Back-End mais il m'arrive de faire des missions de Front de temps en temps et parfois les demandes sont un peu au dessus de mes compétences Front, en l'occurence celle ci.

J'explique donc la situation, j'ai une section en flex divisé en deux blocs côte à côte, le premier qui contient une photo en background (environ 60% de largeur), le second qui contient 3 div contenant des éléments HTML (texte avec mise en forme), chacun de ces blocks fait 100vh de hauteur au minimum, et j'applique un scroll overflow pour qu'on puisse les voir au scroll.

Ce que j'aimerais faire, c'est que lorsqu'on scrolle dans la div de gauche (celle contenant la photo), cela scroll automatiquement dans la div de droite jusqu'à fin du contenu pour scroller normalement sur la page.

Voici mon code actuel pour la section en question :


page-studios {

    margin: 0;
    position: relative;
    padding: 0;
    display: flex;
    justify-content: flex-start;
    align-items: flex-start;

    .picture {
        background-image: url('./../imgs/backgrounds/studios.jpg');
        background-size: cover;
        background-repeat: no-repeat;
        background-position: center center;
        height: $sectionSize;
        width: 60%;
    }

    .studios-list {
        height: $sectionSize;
        overflow: scroll;
        width: 35%;
        margin: 0;
        padding: 0;

        scrollbar-width: none; /* Firefox */
        -ms-overflow-style: none;  /* IE 10+ */
        &::-webkit-scrollbar {
            width: 0px;
            background: transparent; /* Chrome/Safari/Webkit */
        }



<section class="section page-studios">
    <div class="picture scroll-on">

    </div>
    <div class="studios-list scroll-to">
        <div class="studio">
         <!-- Contenu -->
        </div>
    </div>
</section>


J'ai tenté avec le bout de Javascript suivant, mais sans succès :


        let scrollTo = $('.scroll-to');
        $('.scroll-on').scroll(function() {
            scrollTo.prop("scrollTop", $(this).scrollTop)
                .prop("scrollLeft", $(this).scrollLeft);
        });


Selon vous, quelle serait la bonne méthode pour implémenter ce scroll ? Cela pourrait-il venir de mes propriétés CSS ?

Merci à vous d'avance pour votre aide =)

Cordialement,
Alexandre.
Bonjour Jencal et merci pour ta réponse =)

En effet j'étais parti sur quelque chose comme ça au départ, mais le soucis est que ma div de gauche est plus courte que ma div de droite et du coup ça ne fonctionne pas =/

Ma div de gauche fait 100vh de hauteur, et ma div de droite fait actuellement 3 * 100vh (elle fera 5/6 * 100vh de hauteur à terme avec tous les éléments remplis).

Du coup ta solution, tout comme la mienne, ne fonctionne pas avec des hauteurs données =/
Salut Jencal,

Merci encore pour ton aide =)

Mais dans mon cas ça ne fonctionne pas, j'ai repris ton code et l'ai appliqué avec ma structure html, pour que tu puisses mieux te rendre compte, le soucis semble provenir de l'imbrication des divs :

https://codepen.io/SquallX/pen/wLmGQJ

Encore merci =)
Dans ce que tu as fais, testA n'a pas de scroll du tout, impossible de tester du coup
Modifié par JENCAL (01 Jul 2019 - 15:26)
Ah oué donc rien à voir avec la "Synchronisation" entre deux scroll mdrrr j'étais partie loin.

Donc en gros, le mec scroll UNIQUEMENT sur la div de droite, et une fois qu'il est au bout (avec la molette) ça continue sur le body.
Yep c'est ça,

Et il faudrait que ça scroll sur la div de droite même quand il scroll dans la gauche, en gros que ça fasse défiler la droite uniquement jusqu'à ce qu'on arrive au bout de celle-ci.

C'est plus clair je pense haha =)

Encore merci pour ton aide !
Hmmmm...

Pour infos, le scroll est basé sur le survol de la souris... donc cest très complex ta demande.
JENCAL a écrit :
Hmmmm...

Pour infos, le scroll est basé sur le survol de la souris... donc cest très complex ta demande.


Oui justement, je ne sais même pas si c'est possible en réalité =/
Alors je pense que c'est possible, mais l'algo serait long et complexe et je t'avoue, que j'ai pas forcément le temps de pondre un algo comme cela.

En gros , en pseudo code.

-> 1er
// Sur l'event .hover de l'image
// capter le scroll
//calculer la vitesse du scroll, ou autre? le je sais pas du tout
//appliquer le résultat en pixel sur le scroll l'autre div.

->2eme
//au scroll sur l'autre div
//calculer la fin du scroll //facile
//si fin du scroll
//alors le hover = hover sur le body. // compliqué, pas trop cherché
Modifié par JENCAL (01 Jul 2019 - 17:16)
Salut à vous,

Ca me semblait compliqué du coup j'ai changé mon fusil d'épaule, j'aimerais afficher un bloc avec la photo à côté, chaque élément aurait donc sa propre photo, mais dans l'idéal j'aimerais faire un défilement de l'image au scroll.

Seulement je galère un peu à trouver la bonne structure, quel serait le mieux selon vous ?

une div photos et une div contenu en height 100vh avec un overflow scroll, ça pourrait être simple mais je ne vois pas comment gérer l'animation.

Je pensais aussi à une div photos avec la 1ère en absolute et un JS qui viendrait changer les caractéristiques, mais je n'arrive pas à gérer les transitions de façon dynamiques, en effet les données sont gérées en php.

Bref à force de mouliner dans cet exemple je suis assez perdu et je n'avance plus, au cas où voici mon code actuel :


let app = this;
        let tempScrollTop = 0;
        let currentScrollTop = 0;
        $('.studios-content').on('scroll', function(e) {
            currentScrollTop = $(this).scrollTop();
            let studios = $('.page-studios').data('studios');
            studios.forEach((studio) => {
                if( app.isElementInView('#studio_' + studio) ) {
                    if( tempScrollTop > currentScrollTop ) {
                        if( studio - 1 > 0 ) {
                            $('#picture_' + (studio - 1)).css('position', 'initial');
                        }

                        $('picture_' + studio).css('position', 'absolute');
                    }
                    else if (tempScrollTop < currentScrollTop ){
                        $('picture_' + studio).css('position', 'absolute');
                        if( studio + 1 <= studios.length ) {
                            $('#picture_' + (studio + 1)).css('position', 'initial');
                        }
                    }
                }
            });
            tempScrollTop = currentScrollTop;
        });

// Fonction
isElementInView(element, fullyInView) {
            var pageTop = $(window).scrollTop();
            var pageBottom = pageTop + $(window).height();
            var elementTop = $(element).offset().top;
            var elementBottom = elementTop + $(element).height();

            if (fullyInView === true) {
                return ((pageTop < elementTop) && (pageBottom > elementBottom));
            } else {
                return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
            }
        },


CSS :


    .studios-index {
        margin: 0;
        padding: 0;
        width: 100%;
        position: relative;
        display: flex;
        justify-content: flex-start;
        align-items: flex-start;

        .pictures {
            position: relative;
            height: 100vh;
            overflow: hidden;
            width: 60%;

            .picture {
                background-size: cover;
                background-repeat: no-repeat;
                background-position: center center;
                height: 100vh;
                width: 100%;
                //position: absolute;
                //display: none;
                top: 0;
                left: 0;

                &:first-child {
                    position: absolute;
                }

                @include media-breakpoint-down(sm) {
                    width: 100%;
                    height: 30vh;
                    position: absolute;
                }
            }

            @include media-breakpoint-down(sm) {
                width: 100%;
                margin-top: 30vh;
            }
        }

        .studios-content {

            height: 100vh;
            overflow: scroll;
            padding: 5rem 0 5rem 8rem;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            align-items: flex-start;
            width: 40%;
            /* right: 0; */
            /* position: absolute; */
            text-align: left;



<section class="section page-studios" data-studios="{{ json_encode($studiosList) }}">
    <div class="studios-index">
        <div class="pictures">
        @foreach( $studios as $studio )
            <div class="picture" style="background-image: url('{{ $studio->cover }}')" id="picture_{{ $studio->order }}">

            </div>
        @endforeach
        </div>
        <div class="studios-content">
            @foreach( $studios as $studio )
                <div class="studio" id="studio_{{ $studio->order }}">
                    <div class="studio-content" id="content_{{ $studio->order }}">
                    <!-- Contenu -->
                    </div>
                </div>
            @endforeach
        </div>
    </div>
</section>


Pour expliquer ce que j'aimerais, j'ai fait une petit vidéo dans XD :

https://vimeo.com/346846866

Merci pour les plus patients d'entre vous =)

Amicalement,
Alex.
Modifié par SquallX (08 Jul 2019 - 14:32)