javascript - Disable scroll while waiting to for scroll selection animation to complete - Stack Overflow

I'm trying to make customize section-scroll where scroll event is disabled while animation is in m

I'm trying to make customize section-scroll where scroll event is disabled while animation is in motion. I tried with overflow hidden and other similar functions to apply while scroll animation is in progress but no luck.

JS fiddle example

CSS

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

JS example:

$('html').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
//scroll down
    counter++;


    $('body').addClass('stop-scrolling');
    console.log("Start animacije");
    setTimeout(function () {
      $('body.stop-scrolling').removeClass('stop-scrolling');
      console.log("End animation");
    }, 800);



    if (!(counter > maxSections)) {
      $('html, body').animate({
        scrollTop: $( $("#sect-"+counter) ).offset().top
      }, 800);
    }

  } else {
//scroll up
    counter--;


    $('body').addClass('stop-scrolling');
    console.log("Start animation");
    setTimeout(function () {
      $('body.stop-scrolling').removeClass('stop-scrolling');
      console.log("End animation");
    }, 800);


    if (!(counter < 1)) {
      $('html, body').animate({
        scrollTop: $( $("#sect-"+counter) ).offset().top
      }, 800);
    }

  }

  if (counter <= 0) {
    counter = 1;
  }
  else if (counter >= 3) {
    counter = maxSections;
  }

  console.log(counter);
});

If you scroll while animation is in progress, scroll will continue until you reach end of sections.

Is possible to disable scroll event while animation is in progress?

I'm trying to make customize section-scroll where scroll event is disabled while animation is in motion. I tried with overflow hidden and other similar functions to apply while scroll animation is in progress but no luck.

JS fiddle example

CSS

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

JS example:

$('html').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
//scroll down
    counter++;


    $('body').addClass('stop-scrolling');
    console.log("Start animacije");
    setTimeout(function () {
      $('body.stop-scrolling').removeClass('stop-scrolling');
      console.log("End animation");
    }, 800);



    if (!(counter > maxSections)) {
      $('html, body').animate({
        scrollTop: $( $("#sect-"+counter) ).offset().top
      }, 800);
    }

  } else {
//scroll up
    counter--;


    $('body').addClass('stop-scrolling');
    console.log("Start animation");
    setTimeout(function () {
      $('body.stop-scrolling').removeClass('stop-scrolling');
      console.log("End animation");
    }, 800);


    if (!(counter < 1)) {
      $('html, body').animate({
        scrollTop: $( $("#sect-"+counter) ).offset().top
      }, 800);
    }

  }

  if (counter <= 0) {
    counter = 1;
  }
  else if (counter >= 3) {
    counter = maxSections;
  }

  console.log(counter);
});

If you scroll while animation is in progress, scroll will continue until you reach end of sections.

Is possible to disable scroll event while animation is in progress?

Share Improve this question edited Oct 22, 2020 at 20:10 Umutambyi Gad 4,1113 gold badges20 silver badges40 bronze badges asked Oct 22, 2020 at 19:56 SlasherSlasher 61810 silver badges32 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3 +100

Here's simple fix with less code modification.

Just declare a variable that represents scrolling state. And using this state you can ignore ining scroll events if currently scrolling.

let scrolling = false;

$('html').on('wheel', function(event) {
  if (scrolling) {
    return;
  } else {
    scrolling = true;
    setTimeout(function () {
      scrolling = false;
    }, 800 /* animation duration */);
  }

  ...

Here's final fiddle link.

Using setTimeout function you can reset scrolling state to false so, new events will be received.

Instead of using CSS, you can use your script to block scroll events.

You can use the onComplete parameter of the .animate method to run a callback after animation ends.

With this, you can use a flag variable to determine whether or not the page is scrolling.

The whole process would be something like:

  1. Animation started.
  2. Flag animating = true.
  3. Block scrolling.
  4. Animation ended.
  5. Flag animating = false.
  6. Unblock scrolling.

Here's a minimal and reproducible example. It may have some bugs, but it should solve your main problem.

$(document).ready(function(){

  'use strict';
  
  // Flag to decide whether or not scroll is allowed.
  let animating = false;

  $(window).on('scroll', (e) => {
    if (animating){
      // Block scroll
      e.preventDefault();
    }
  });
  
  $('.section').on('wheel', e => {
    e.stopPropagation();
  
    // Do not run this function again when animation is happening.
    if (animating){
      return;
    }
  
    const $target = $(e.target);
    const isScrollDown = e.originalEvent.deltaY > 0;

    // Choose whether to scroll to next or previous section.
    const $targetSection = isScrollDown ? $target.next('.section') : $target.prev('.section');
    // Check whether or not there is a target
    const hasTargetSection = $targetSection.length > 0;

    // Only animate when there is a target.
    if (hasTargetSection){
      // Flag animation start
      animating = true;
      $('html, body').animate(
        // Animation properties
        {
          scrollTop: $targetSection.offset().top
        },
        // Animation duration
        800,
        // Function to run after animation ends
        () => {
          // Flag animation ended
          animating = false;
        }
      );
    }
  });

});
html, body, #app {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

.section {
  width: 100%;
  height: 100%;
  font-size: 3em;
  display: flex;
  justify-content: center;
  align-items: center;
}

.a {
  background-color: #f008;
}

.b {
  background-color: #0f08;
}

.c {
  background-color: #00f8;
}
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="app">
  <div class="section a">Section A</div>
  <div class="section b">Section B</div>
  <div class="section c">Section C</div>
</div>

What you are asking for is called throttling. I remend you read this link to understand it better.

So to fix your code, you only need to enable throttling for your wheel event listener.

Like this:

let throttle = (fn, timedelay) => {
  let pass = true;
  return function () {
    if (pass) {
      setTimeout(() => {
        fn.apply(this, arguments);
        pass = true;
      }, timedelay);

      pass = false;
    }
  };
};

let scrollFunction = throttle(function(event) {
  // your code
}, 200); // 200 miliseconds sounds good

$('html').on('wheel', scrollFunction);

Here is a working code: https://jsfiddle/d1fcL5en/

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745259100a4619126.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信