在jquery scrollTop动画完成后滚动显示 [英] Scroll fires after jquery scrollTop animate completed

查看:94
本文介绍了在jquery scrollTop动画完成后滚动显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么另一个滚动事件被调用 一个 scrollTop 动画会触发完成回调?

Why does another scroll event get called after a scrollTop animation fires its complete callback?

点击处理程序:

var lock = false;

$('#id').click(function(event) {
    var pos;
    if (lock) {
        return;
    }
    lock = true;
    pos = 150;

    console.log("jump start");

    $(jQuery.browser.webkit ? "body": "html").animate({ scrollTop: pos }, 150, function () {
        lock = false;
        console.log("jump end");
    });
});

Scroll Handler:

Scroll Handler:

$(window).scroll(function (e) {
    console.log("scrolling");

    if (!lock){
        alert('1');
    }
});

日志:

jump start
scrolling
jump end
scrolling

关于jsfiddle的演示

推荐答案

背景

jQuery scrollTop()使用scrollTo()这是一个fire and forget事件。滚动没有停止的事件。滚动事件从scrollTo带外发生。 scrollTo表示'开始滚动',滚动事件表示'滚动(某个位置)'。 scrollTo只是启动滚动的开始,它不保证滚动返回时完成。因此,jQuery动画在最终滚动之前完成(甚至可以备份多个滚动)。替代方案是jQuery等待滚动的位置是它所要求的(根据我的解决方案),但它不会这样做

jQuery scrollTop() uses scrollTo() which is a fire and forget event. There is no stopped event for scrolling. The scroll events occur out of band from scrollTo. scrollTo means 'start scroll', a scroll event means 'scrolled (some position)'. scrollTo just initiates the starting of the scroll, it doesn't guarantee that scrolling finished when it returns. So, jQuery animation completes before final scroll (there could even be multiple scrolls backed up). The alternative would be for jQuery to wait for the position of the scroll to be what it requested (per my soln), but it does not do this

这将是不错的如果有一个我们可以指出描述这个的规范,但它只是没有规范的0级dom元素之一, 见这里 。我认为它的工作方式是有道理的,这就是为什么所有浏览器似乎都是这样实现的。

It would be nice if there was a specification that we could point to describing this, but it is just one of the Level 0 dom elements without a spec, see here. I think it makes sense the way that it works, which is why all browsers seem to implement it this way.

为什么会发生这种情况

以下内容出现在动画的最后一个卷轴上:

The following occurs on the last scroll of the animation:


  1. jquery:'窗口请滚动最后一点'

  2. 窗口:'我从jquery收到此消息滚动我现在就开始'

  3. jquery:'woohoo我完成了动画,我将完成'

  4. 您的代码: lock = false; console.log(jump end);

  5. 窗口:'我已滚动'调用滚动事件处理程序。'

  6. 您的代码: $(窗口)。 scroll(function(e){'为什么会发生这种情况?'

  1. jquery: 'Window please scroll this last bit'
  2. Window: 'I got this message from jquery to scroll I will start that now'
  3. jquery: 'woohoo I am finished the animation, I will complete'
  4. Your code: lock = false;console.log("jump end");
  5. Window: 'I have scrolled' call scroll event handlers.'
  6. Your code: $(window).scroll(function (e) { 'Why is this happening?'

正如你所看到的那样jquery做了在完成动画之前不要等待动画的最后滚动步骤完成(继续执行步骤4)。部分原因是因为滚动没有停止的事件,部分原因是因为这是因为e jquery不会等待滚动位置到达请求的位置。我们可以检测到我们何时到达目的地位置,如下所述。

As you can see jquery does not wait for the final scroll step of the animation to complete before completing the animation (going on to step 4). Partly this is because there is no stopped event for scrolling and partly this is because jquery does not wait for the scroll position to reach the position that was requested. We can detect when we have reached the destination position as described below.

解决方案

滚动完成时没有停止的事件。 请参阅此处 。有意义的是没有停止的事件,因为用户可以在任何点再次开始滚动,因此滚动没有真正停止的点 - 用户可能只是暂停了几分之一秒。

There is no stopped event for when scrolling completes. See here. It makes sense that there is no stopped event because the user could start scrolling again at any point, so there is no point where scrolling has really stopped - the user might just have paused for a fraction of a second.

用户滚动:对于用户滚动,正常的方法是等待一段时间,看看滚动是否完整,如答案中所述引用的问题(请记住,用户可以再次开始滚动)。

User scrolling: For user scrolling, the normal approach is to wait some amount of time to see if scrolling is complete as described in the answer of the referenced question (bearing in mind that the user could start scrolling again).

scrollTop :但是,由于我们知道滚动到的位置,我们可以做得更好。

scrollTop: However, since we know the position that we are scrolling to we can do better.

参见 这个小提琴。

See this fiddle.

它的关键在于,因为我们知道滚动到哪里,所以我们可以存储该位置。当我们到达那个位置时,我们知道我们已经完成了。

The crux of it is that since we know where we are scrolling to, we can store that position. When we reach that position we know that we are done.

输出现在是:

jump start
scroll animation
jump end

代码是(注意这是基于你的小提琴而不是比编辑问题中的代码):

The code is (note that this is based off your fiddle rather than the code in the edited question):

var scrollingTo = 0;
$('#id').click(function(event) {    
    if (scrollingTo) {
        return;
    }        
    console.log("jump start");
    scrollingTo = 150;
    $(jQuery.browser.webkit ? "body": "html").animate({ scrollTop: scrollingTo }, 150, function () {                
    });
});

function handleScroll()
{    
    if( scrollingTo !== 0  && $(window).scrollTop() == scrollingTo)
    {
        scrollingTo = 0;
        console.log("jump end");    
    }
}

$(window).scroll(function (e) {    
    if (!scrollingTo){
        console.log('user scroll');
    } else {
        console.log("scroll animation");
    }
    handleScroll();
});

这篇关于在jquery scrollTop动画完成后滚动显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆