Search code examples
javascriptjqueryhtmlcssparallax

scroll through "stack" of DOM objects


I have this fiddle:

https://jsfiddle.net/72p0rkqd/

html:

<section id="contact"></section>
<section id="works"></section>
<section id="about"></section>
<section id="home"></section>

css:

section {
  display: flex;
  position: fixed;
  width: 100vw;
  min-height: 100vh;
}

#home {
  background-color: black;
}

#about {
  background-color: red;
}

#works {
  background-color: purple;
}

#contact {
  background-color: blue;
}

which reflects my site

right now, the four sections lay on top of each other. what I want is when we begin to scroll at the site, it will scroll through the stack of sections. When we scroll, it will first scroll through #home, so #home scrolls up, making #about visible, and when #home is not on the screen anymore, it will begin scrolling #about upwards, making #works visible and so on. When you then scroll up on the page, the sections should begin stacking themself again, reverting the downscroll process.

How can this be done?


Solution

  • Here a solution I found. Maybe it's not the best answer and it certainly have to be improved.

    I got it using animate() to move up/down the sections and "DOMMouseScroll" & "mousewheel" to get wheel moves from jQuery.

    I had to use some flags to prevent from long scrolls.

    Here is the jQuery :

    var homeAnimating = false;
    var aboutAnimating = false;
    var worksAnimating = false;
    var contactAnimating = false;
    
    $('#home').on('DOMMouseScroll mousewheel', function (e) {
      if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY
        //scroll down
        if(homeAnimating) {
            return;
        }
            $('#home').animate({
              'marginTop' : "-=100vh" //moves up
            });
            homeAnimating = true;
            aboutAnimating = false;
      }
      //prevent page from scrolling
      return false;
    });
    
    $('#about').on('DOMMouseScroll mousewheel', function (e) {
      if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY
        //scroll down
        if(aboutAnimating) {
            return;
        }
           $('#about').animate({
             'marginTop' : "-=100vh" //moves up
           });
           aboutAnimating = true;
           worksAnimating = false;
      } else {
        //scroll up
        if(aboutAnimating) {
            return;
        }
           $('#home').animate({
             'marginTop' : "+=100vh" //moves down
           });
           aboutAnimating = true;
           homeAnimating = false;
      }
      //prevent page fom scrolling
      return false;
    });
    
    $('#works').on('DOMMouseScroll mousewheel', function (e) {
      if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY
        //scroll down
        if(worksAnimating) {
            return;
        }
            $('#works').animate({
              'marginTop' : "-=100vh" //moves up
            });
            worksAnimating = true;
            contactAnimating = false;
      } else {
        //scroll up
        if(worksAnimating) {
            return;
        }
           $('#about').animate({
             'marginTop' : "+=100vh" //moves down
           });
           aboutAnimating = false;
           worksAnimating = true;
      }
      //prevent page fom scrolling
      return false;
    });
    
    $('#contact').on('DOMMouseScroll mousewheel', function (e) {
      if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY
      } else {
        //scroll up
        if(contactAnimating) {
            return;
        }
            $('#works').animate({
              'marginTop' : "+=100vh" //moves down
            });
            contactAnimating = true;
            worksAnimating = false;
      }
      //prevent page fom scrolling
      return false;
    });
    

    And here is the fiddle : https://jsfiddle.net/fkahogqd/

    Hope it helps.

    EDIT

    Ok, that was a little tricky but I assume that's what you're looking for :

    Here is the new jQuery :

    var winHeight = $(window).height();
    
    $('section').on('DOMMouseScroll mousewheel', function (e) {
      if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
      
        var homePos = parseInt($('#home').css('marginTop'),10);
        var aboutPos = parseInt($('#about').css('marginTop'),10);
        var worksPos = parseInt($('#works').css('marginTop'),10)
    
        //scroll down
            $('#home').animate({
              'marginTop' : "-=5vh" //moves up
            },2);
            if (homePos <= - winHeight) {
                $('#home').stop();
              $('#about').animate({
                'marginTop' : "-=5vh"
              },2);
            }
            if (aboutPos <= - winHeight) {
                $('#about').stop();
              $('#works').animate({
                'marginTop' : "-=5vh"
              },2);
            }
            if (worksPos <= - winHeight) {
                $('#works').stop();
            }
      } else {
    
            var homePos = parseInt($('#home').css('marginTop'),10);
            var aboutPos = parseInt($('#about').css('marginTop'),10);
            var worksPos = parseInt($('#works').css('marginTop'),10)
    
            $('#works').animate({
              'marginTop' : "+=5vh" //moves up
            },2);
            if (worksPos >= 0) {
                $('#works').stop();
              $('#about').animate({
                'marginTop' : "+=5vh"
              },2);
            }
            if (aboutPos >= 0) {
                $('#about').stop();
              $('#home').animate({
                'marginTop' : "+=5vh"
              },2);
            }
            if (homePos >= 0) {
                $('#home').stop();
            }           
      }
    });
    

    And here is the fiddle : https://jsfiddle.net/fkahogqd/5/

    Hope it helps.