我将2条连续的消息推送到消息队列,但它们似乎没有被连续调用

时间:2015-07-17 03:04:58

标签: javascript jquery javascript-events

如果事件是由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在scroll函数运行后触发step事件。 setTimeout()将匿名函数推送到消息队列的末尾。紧接着,JQuery将scroll事件推送到消息队列的末尾。

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

  1. 无关紧要的事情
  2. 无关紧要的事情
  3. ignoreNext =真
  4. 滚动事件(将ignoreNext设置为false)
  5. 无关紧要的事情
  6. 无关紧要的事情
  7. 因此,如果“无关紧要的东西”之一是用户触发的滚动事件,则应停止并重新启动动画。然而,这种情况并非如此。每次触发滚动事件(即使是用户),ignoreNext都是真的。因此,用户无法中断动画。

    为什么会发生这种情况?如何让用户中断动画?

1 个答案:

答案 0 :(得分:0)

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

如果是这样,你需要稍微重构一下。

首先,在1函数

下抽象出需要在scroll事件上运行的所有逻辑
function defaultScroll(e) {
    console.log("scroll event ", e);
}

然后,一种附加或分离此逻辑以滚动事件的方法,如下所示,请注意namespaced events

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

function detachScrollEvent() {
    $element.off("scroll.element");
}

休息只是在需要启用或禁用滚动事件时找到一种方法来调用attachScrollEventdetachScrollEvent

在您的情况下,您希望在detachScrollEvent期间致电$('#element').animate({...}),并在动画完成后致电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);
}

哦,当然,链接到fiddle

用户滚动时禁用滚动动画

如果用户通过点击一堆事件进行滚动并查看用户是否启动了以下任何内容(有点hacky),则可以停止滚动动画:

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/

希望有所帮助