问题描述
如果事件是由$().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);
}
});
});
step
功能运行后,jQuery将触发scroll
事件。
setTimeout()
将匿名函数推到消息队列的末尾。
之后,JQuery立即将scroll
事件推送到消息队列的末尾。
我以为消息队列看起来像这样:
- 不相关的东西
- 不相关的东西
- ignoreNext =真
- 滚动事件(将ignoreNext设置为false)
- 不相关的东西
- 不相关的东西
因此,如果“无关紧要”之一是由用户触发的滚动事件,则应停止并重新启动动画。
然而,这种情况并非如此。
每当滚动事件被触发(甚至由用户触发)时, ignoreNext
为true。
因此,用户不能中断动画。
为什么会发生这种情况,如何允许用户中断动画?
1楼
似乎您正在尝试通过jQuery动画滚动元素时停止默认的滚动事件逻辑吗?
如果是这样,则需要对其进行一些重构。
首先,抽象出需要在1函数下的滚动事件上运行的所有逻辑
function defaultScroll(e) {
console.log("scroll event ", e);
}
然后,一种附加或分离此逻辑以滚动事件的方法,如下所示,注意 :
function attachScrollEvent() {
$element.on("scroll.element", defaultScroll);
}
function detachScrollEvent() {
$element.off("scroll.element");
}
剩下的就是寻找一种在需要启用或禁用滚动事件时调用attachScrollEvent
或detachScrollEvent
的方法。
在你的情况,你会想打电话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);
}
哦,当然,链接到
用户滚动时禁用滚动动画
如果用户通过滚动进入一系列事件并查看用户是否发起了以下任何事件(有点怪癖),则可以滚动滚动动画,如下所示:
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();
}
});
更新的小提琴: :
希望能有所帮助