如何检查每个新滚动并避免Apple鼠标问题(多滚动效果)

时间:2012-10-04 12:23:14

标签: javascript jquery macos mousewheel

我尝试制作鼠标滚轮事件脚本,但由于我使用的是Apple Magic Mouse鼠标及其继续滚动功能,因此遇到了一些问题。

我想这样做http://jsfiddle.net/Sg8JQ/(来自jQuery Tools Scrollable with Mousewheel - scroll ONE position and stop,使用http://brandonaaron.net/code/mousewheel/demos),但我想要一个简短的动画(如250毫秒)滚动到方框,并且能够经历多个在一个动画中多次滚动时的框。 (如果我滚动,动画开始滚动到第二个框,但如果我再次滚动,我想转到第三个,如果我滚动两次,到第四个,等等。)

我首先想到stopPropagation / preventDefault / return false;可以“停止”鼠标滚轮速度(和var delta) - 所以我可以计算新滚动事件的数量(可能与一个计时器) - ,但没有一个。

想法?

编辑:如果您尝试使用这些鼠标在Google日历中滚动,则会切换多个日历,而不仅仅是一个日历。似乎他们也无法解决这个问题。

编辑2:我认为解除鼠标滚轮并在可以停止鼠标滚轮监听器后再次绑定(并且不要听惯性结束)。它没有。

编辑3:尝试使用日期(感谢this post),不是最优的,但总比没有好http://jsfiddle.net/eZ6KE/

3 个答案:

答案 0 :(得分:1)

最好的方法是使用超时并在侦听器内检查超时是否仍然有效:

var timeout = null;
var speed = 100; //ms
var canScroll = true;

$(element).on('DOMMouseScroll mousewheel wheel', function(event) {
    // Timeout active? do nothing
    if (timeout !== null) {
        event.preventDefault();
        return false;
    }

    // Get scroll delta, check for the different kind of event indexes regarding delta/scrolls
    var delta = event.originalEvent.detail ? event.originalEvent.detail * (-120) : (
            event.originalEvent.wheelDelta ? event.originalEvent.wheelDelta : (
                    event.originalEvent.deltaY ? (event.originalEvent.deltaY * 1) * (-120) : 0
    ));

    // Get direction
    var scrollDown = delta < 0;

    // This is where you do something with scrolling and reset the timeout
    // If the container can be scrolling, be sure to prevent the default mouse action
    // otherwise the parent container can scroll too
    if (canScroll) {
        timeout = setTimeout(function(){timeout = null;}, speed);
        event.preventDefault();
        return false;
    }

    // Container couldn't scroll, so let the parent scroll
    return true;
});

你可以将它应用于任何可滚动元素,在我的例子中,我使用了jQuery工具可滚动库,但最终大量定制它以改进浏览器支持以及添加特定于我的用例的自定义功能。

您要注意的一件事是确保超时足够长,以防止多个事件无缝触发。只有当您想要控制元素的滚动速度以及应该一次滚动多少元素时,我的解决方案才有效。如果将console.log(event)添加到侦听器功能的顶部并使用连续滚动外围设备滚动,则会看到许多鼠标滚轮事件被触发。

令人讨厌的是,Firefox滚动DOMMouseScroll 不会在魔术鼠标或连续滚动设备上触发 ,但对于具有滚动并停止通过点击循环的普通滚动设备鼠标滚轮。

答案 1 :(得分:0)

我的网站上遇到了类似的问题,经过多次尝试失败后,我编写了一个函数,它计算了所选框的总偏移量并开始动画。它看起来像这样:

function getOffset() {
    var offset = 0;
    $("#bio-content").children(".active").prevAll().each(function (i) {
        offset += $(this)[0].scrollHeight;
    });
    offset += $("#bio-content").children(".active")[0].scrollHeight;

    return offset;
}

var offset = getOffset();
$('#bio-content').stop().animate( {
            scrollTop: offset
}, animationTime);

我希望它能让你了解如何达到你想要的效果。

答案 2 :(得分:0)

您可以尝试检测车轮何时停止移动,但这会延迟您的响应时间

$(document).mousewheel(function() {
  clearTimeout($.data(this, 'timer'));
  $.data(this, 'timer', setTimeout(function() {
     alert("Haven't scrolled in 250ms!");
     //do something
  }, 250));
});

源: jquery mousewheel: detecting when the wheel stops?

或实现避免开始新动画的标志

var isAnimating=false;

$(document).bind("mousewheel DOMMouseScroll MozMousePixelScroll", function(event, delta) {
   event.preventDefault();
   if (isAnimating) return;
   navigateTo(destination);
});

function navigateTo(destination){
   isAnimating = true;
   $('html,body').stop().animate({scrollTop: destination},{complete:function(){isAnimating=false;}});
}