我将两个连续的消息推入消息队列,但它们似乎没有被连续调用

I pushed 2 consecutive messages to the message queue, but they don't seem to be called consecutively

本文关键字:消息 连续 调用 两个 队列      更新时间:2023-09-26

我试图让scroll事件处理程序忽略事件,如果事件是由$().animate()触发的。下面是我的尝试:

var ignoreNext=false;
$('#element').on('scroll',function(){
    if(ignoreNext){
        ignoreNext=false;
        return;
    }
    $('#element').stop(true); // stop animation if the user triggered the scroll event
    $('#element').animate({
        scrollTop:...
    },{
        step:function(){
            setTimeout(function(){ // push to message queue right before the scroll event is pushed by $().animate()
                ignoreNext=true;
            },0);
        }
    });
});

JQuery在step函数运行后触发scroll事件。setTimeout()将匿名函数推到消息队列的末尾。紧接着,JQuery将scroll事件推到消息队列的末尾。

我假设消息队列看起来像这样:

  1. 一些无关紧要的
  2. 一些无关紧要的
  3. ignoreNext = true
  4. 滚动事件(设置ignoreNext为false)
  5. 一些无关紧要的
  6. 一些无关紧要的

因此,如果其中一个"无关的事情"是由用户触发的滚动事件,那么动画应该停止并重新启动。然而,事实并非如此。每次触发滚动事件时(甚至是由用户触发),ignoreNext为true。因此,用户不能中断动画。

为什么会发生这种情况,我如何允许用户中断动画?

它似乎是你试图停止默认的滚动事件逻辑时,元素通过jQuery动画滚动?

如果是的话,你需要稍微重构一下。

首先,抽象出需要在1个函数

下的滚动事件上运行的所有逻辑
function defaultScroll(e) {
    console.log("scroll event ", e);
}

然后,一种将此逻辑附加或分离到滚动事件的方法,如下所示,注意命名空间事件:

function attachScrollEvent() {
    $element.on("scroll.element", defaultScroll);
}
function detachScrollEvent() {
    $element.off("scroll.element");
}

Rest只是找到一种方法来调用attachScrollEventdetachScrollEvent当你需要启用或禁用滚动事件。

在您的情况下,您希望在$('#element').animate({...})期间调用detachScrollEvent,并在动画完成后调用attachScrollEvent。如下所示:

detachScrollEvent();
$element.animate({
    scrollTop: 200
}, 
{
    done: function() {
        setTimeout(attachScrollEvent, 0);
    }
});

这是完整的代码(如果这是你想要的功能,我很乐意注释掉)

var $element = $("#element");
var $scrollButton = $(".js-auto-scroll");
var $output = $(".output");
attachScrollEvent();
$scrollButton.on("click", function(e) {
    e.preventDefault();
    detachScrollEvent();
    $element.animate({
        scrollTop: 200
    }, 
    {
        done: function() {
            setTimeout(attachScrollEvent, 0);
        }
    });
});
function attachScrollEvent() {
    $element.on("scroll.element", defaultScroll);
    var result = "<p>scroll event is <span class='green'>attached</span>.</p>";
    $output.html(result);
}
function detachScrollEvent() {
    $element.off("scroll.element");
    var result = "<p>scroll event is <span class='red'>detached</span>.</p>";
    $output.html(result);
}
function defaultScroll(e) {
    var scrollTop = e.currentTarget.scrollTop;
    var result = "<p>scrolled to: " + scrollTop + "px</p>";
    $output.html(result);
}

哦,当然,还有小提琴的链接


当用户滚动

时禁用滚动动画如果用户滚动,可以通过点击一系列事件并查看用户是否启动了其中的任何一个事件来停止

滚动动画,如下所示:

var allPossibleEventsThatCanStopAnimation = "scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove";
$element.on(allPossibleEventsThatCanStopAnimation, function(e) {
    if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel") {
        $element.stop();
        detachScrollEvent();
        attachScrollEvent();
    }
});

更新小提琴:http://jsfiddle.net/Varinder/poLosmp9/3/

希望有帮助