简体   繁体   English

如何仅监听javascript / jquery上的第一个滚动事件?

[英]How to listen to only the first scroll event on javascript/jquery?

I'm currently working on implementing my own version of snap-scrolling using vanilla JavaScript, and while I've got it mostly working as of now, I'm having trouble handling the scroll events. 我目前正在使用香草JavaScript来实现自己的快照滚动版本,尽管到目前为止我几乎可以正常使用它,但是在处理滚动事件时遇到了麻烦。

My HTML looks something like this: 我的HTML看起来像这样:

<div class="container">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
  <div id="item4"></div>
</div>

And my JS looks something like this: 我的JS看起来像这样:

var pos = 0;
var isScrolling = false;
var id = 1;

$(window).scroll(function() {
  if (!isScrolling) {
    isScrolling = true;
    var curPos = $(this).scrollTop();
    if (curPos > pos) {
      // scrolling down
      if (id < 4) {
        id++;
        $('html, body').animate({
          scrollTop: $('#item' + id).offset().top
        }, 500);
      }
    } else {
      // scrolling up
      if (id > 1) {
        id--;
        $('html, body').animate({
          scrollTop: $('#item' + id).offset().top
        }, 500);
      }
    }
    isScrolling = false;
    pos = curPos;
  }
});

What currently happens is when I scroll down my mouse wheel, it will do the animation but will keep proceeding to the next divs because of the multiple scroll events being fired. 当前发生的是,当我向下滚动鼠标滚轮时,它将进行动画处理,但是由于触发了多个滚动事件,因此将继续前进到下一个div。 How do I make it so that it only listens to the first event (whether it scrolls up or down)? 我如何使它仅侦听第一个事件(无论它是向上滚动还是向下滚动)?

A hacky way is to use timer: 一种怪癖的方法是使用计时器:

var pos = 0;
var isScrolling = false;
var id = 1;
var lastScrollTime = $.now();

$(window).scroll(function() {
  if ((!isScrolling)&&((($.now()-lastScrollTime)>3000)) {
    isScrolling = true;
    var curPos = $(this).scrollTop();
    if (curPos > pos) {
      // scrolling down
      if (id < 4) {
        id++;
        $('html, body').animate({
          scrollTop: $('#item' + id).offset().top
        }, 500);
      }
    } else {
      // scrolling up
      if (id > 1) {
        id--;
        $('html, body').animate({
          scrollTop: $('#item' + id).offset().top
        }, 500);
      }
    }
    isScrolling = false;
    pos = curPos;
    lastScrollTime = $.now();
  }
});

You can register one time listeners in jQuery using jQuery.one . 您可以使用jQuery.one在jQuery中注册一次侦听jQuery.one

EDIT: You can use the complete callback of jQuery.animate to stop/start responding to scroll events. 编辑:您可以使用jQuery.animatecomplete回调来停止/开始响应滚动事件。

var isScrolling = false;
$(window).on('scroll', function () {
    if (!isScrolling) {
        isScrolling = true;
        var curPos = $(this).scrollTop();
        if (curPos > pos) {
            // scrolling down
            if (id < 4) {
                id++;
                $('html, body').animate({
                    scrollTop: $('#item' + id).offset().top
                }, 500,function(){
                    isScrolling = false;
                });
            }
        } else {
            // scrolling up
            if (id > 1) {
                id--;
                $('html, body').animate({
                    scrollTop: $('#item' + id).offset().top
                }, 500,function(){
                    isScrolling = false;
                });
            }
        }
        pos = curPos;
    }
});

There's no easy way to deal with what it is known as kinetic scrolling . 没有简单的方法来处理所谓的动态滚动 Browsers do not provide developers a proper way to distinguish the meaningful scrolling from the inertial ones. 浏览器没有为开发人员提供一种区分有意义的滚动和惯性滚动的正确方法。

However, there are some attempts out there that aims to solve this issue, such as Lethargy . 但是,有一些旨在解决此问题的尝试,例如Lethargy Not 100% ideal, but very close to it. 不是100%理想,但非常接近。

Other than that, you can take a look at libraries like fullPage.js where another attempt to solve the issue was made. 除此之外,您还可以查看fullPage.js之类的 ,在此库中又尝试解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM