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

标签 javascript jquery jquery-events

如果事件是由 $().animate() 触发的,我正在尝试让 scroll 事件处理程序忽略该事件。这是我尝试过的:

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 animate 滚动时,您似乎试图停止默认的滚动事件逻辑?

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

首先,抽象出1个函数下需要在滚动事件上运行的所有逻辑

function defaultScroll(e) {
    console.log("scroll event ", e);
}

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

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

哦,当然,链接到 fiddle

<小时/>

用户滚动时禁用滚动动画

如果用户通过点击一堆事件并查看用户是否启动了其中任何一个事件(有点黑客)来滚动,则可以停止滚动动画,如下所示:

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

更新的 fiddle :http://jsfiddle.net/Varinder/poLosmp9/3/

希望有帮助

关于javascript - 我连续推送了2条消息到消息队列,但它们似乎没有被连续调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467801/

相关文章:

jQuery Mobile 磨砂页眉

javascript - 禁用链接的默认行为

javascript - 如何在全局 JavaScript 变量等于某个值时触发 Google 跟踪代码管理器事件

javascript - javascript 数组对象逻辑中的小问题

javascript - 在替换中使用 Javascript 非捕获组

javascript - jQuery 绑定(bind)长度变化

javascript - javascript 或 jquery 中的 toPlatedString 等效项

javascript - Bootstrap 选项卡在 jQuery-UI 对话框窗口中无法正常工作

javascript - JavaScript 和/或 jQuery 中的函数监听器

javascript - 使用自定义 JavaScript 监控用户行为