簡體   English   中英

在等待滾動選擇動畫完成時禁用滾動

[英]Disable scroll while waiting to for scroll selection animation to complete

我正在嘗試自定義section-scroll ,其中在動畫運行時禁用滾動事件。 我嘗試在滾動動畫正在進行時應用溢出隱藏和其他類似的功能,但沒有運氣。

JS小提琴示例

CSS

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

JS示例:

$('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);
});

如果您在動畫播放時滾動,滾動將繼續,直到您到達部分末尾。

是否可以在動畫進行時禁用滾動事件?

您可以使用腳本來阻止滾動事件,而不是使用 CSS。

您可以使用.animate方法onComplete參數在動畫結束后運行回調。

有了這個,您可以使用標志變量來確定頁面是否正在滾動。

整個過程大概是這樣的:

  1. 動畫開始了。
  2. 標記動畫 = 真。
  3. 阻止滾動。
  4. 動畫結束。
  5. 標記動畫 = false。
  6. 取消阻止滾動。

這是一個最小且可重復的示例。 它可能有一些錯誤,但它應該可以解決您的主要問題。

 $(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.com/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>

這是具有較少代碼修改的簡單修復。

只需聲明一個代表滾動狀態的變量。 如果當前正在滾動,則使用此狀態您可以忽略傳入的滾動事件。

let scrolling = false;

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

  ...

這是最后的小提琴鏈接

使用setTimeout函數可以將滾動狀態重置為false以便接收新事件。

您所要求的稱為節流。 我建議您閱讀此鏈接以更好地理解它。

所以要修復你的代碼,你只需要為你的wheel事件監聽器啟用節流。

像這樣:

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);

這是一個工作代碼: https : //jsfiddle.net/d1fcL5en/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM