Vertical scrolling with jQuery

1

I have 2 problems, what I'm doing is not working, if I put overflow = hidden

and it works if I move from one to two, but two to one does not work, it gets caught.

Let's see if you can lend me a hand

$(document).ready(function() {  

/******** Desplazamiento vertical ********/

$(function () {
  var $win = $(window);
  var $pos = $(window).height();
  var uno = $(".uno").offset().top;
  var dos = $(".dos").offset().top;

  $win.scroll(function () {
    if ($win.scrollTop() <= $pos) {
      $("html, body").animate({
        scrollTop: dos
      }, 2000);
    }
    else  {
      $("html, body").animate({
          scrollTop: uno
      }, 2000);
    }    
  }); 
});

   /********  ********/

});
.uno {
  background-color: blue;
  top: 0;
  left: 0;
  width: auto;
  height: 100vh;
}

.dos {
  background-color: red;
  top: 0;
  left: 0;
  width: auto;
  height: 100vh;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<main>
<section class="uno">
</section>
<section class="dos">
</section>
</body>
</html>
    
asked by Isaac Palacio 15.06.2018 в 13:17
source

1 answer

0

The code has some problems:

  • You do not control if the scroll is produced by the user or generated by the animation itself, which will cause the animation function to fire several times.

  • $win.scrollTop() <= $pos will always be true when you try to move from "two" to "one" because the height of the section is equal to the height of the window, so whenever you try to scroll "two" "to" one "the animation will trigger as if you were doing from" one "to" two ".

One option you can follow to correct those problems:

  • Add a variable that controls whether the scroll is being produced by the animation and gives it the value false by default. This variable will work as a traffic light to prevent it from firing several times.
  • Add a variable that controls which section is active. Give the value "one" by default.
  • Inside the animation driver:

    • Make the animation run only if it is not already running (checking the value of the variable created in point 1 is false ).
    • Update the value of the variable created in point 1 to true .
    • Instead of checking the height, check the active section (checking the value of the variable created in point 2).

        

      Note: this method works for two sections; If you have more, in addition to comparing the active section, you should check if the scroll has been done up or down to go to the corresponding section. But it seems that your example is particular for two, so there should be no problem.

    • Add a function that will run when the animation completes and in which : the variable created in point 1 will be reset to false (so that animations are repeated again) and the name of the current section will be updated (from "one" to "two" or vice versa).

        

      Note: I had to add a small delay to the reset of the variable animacion because it does not seem to match the last part of the animation and it was triggered (going back to the original point).

  • Here you can see those changes working:

    var animacion = false;
    var actual = "uno";
    
    $(document).ready(function() {
    
      /******** Desplazamiento vertical ********/
    
      $(function() {
        var $win = $(window);
        var $pos = $(window).height();
        var uno = $(".uno").offset().top;
        var dos = $(".dos").offset().top;
    
        $win.scroll(function() {
    
          if (!animacion) {
            animacion = true;
            if (actual == "uno") {
              $("html,body").animate({
                scrollTop: dos
              }, 
              2000, 
              function() {
                setTimeout("animacion = false", 20);
                actual = "dos";
              });
            } else {
              $("html,body").animate({
                scrollTop: uno
              }, 
              2000,
              function() {
                setTimeout("animacion = false", 20);
                actual = "uno";
              });
            }
          }
        });
      });
    
      /********  ********/
    
    });
    .uno {
      background-color: blue;
      top: 0;
      left: 0;
      width: auto;
      height: 100vh;
    }
    
    .dos {
      background-color: red;
      top: 0;
      left: 0;
      width: auto;
      height: 100vh;
    }
    
    html,
    body {
      margin: 0;
      padding: 0;
      border: 0;
    }
    <html>
    
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    </head>
    
    <body>
      <main>
        <section class="uno">
        </section>
        <section class="dos">
        </section>
      </main>
    </body>
    
    </html>
        
    answered by 19.06.2018 в 20:43