在OSX中停止鼠标轮事件发生两次

10 javascript macos jquery scroll

我注意到鼠标轮事件在mac osx中多次发生.可以归因于惯性功能.

有没有办法解决这个问题?

(自签名ssl请不要担心!) https://sandbox.idev.ge/roomshotel/html5_v2/

我正在使用scrollSections.js https://github.com/guins/jQuery.scrollSections

它使用mousewheel jquery插件:https://github.com/brandonaaron/jquery-mousewheel

我看到很多人都有同样的问题:https://github.com/brandonaaron/jquery-mousewheel/issues/36

有一些解决方案但没有一个与scrollSections插件一起使用.

任何想法如何从JS禁用这个惯性功能?

我试图修复:

// Fix for OSX inertia problem, jumping sections issue.
if (isMac) {

  var fireEvent;
  var newDelta = deltaY;

  if (oldDelta != null) {

    //check to see if they differ directions
    if (oldDelta < 0 && newDelta > 0) {
      fireEvent = true;
    }

    //check to see if they differ directions
    if (oldDelta > 0 && newDelta < 0) {
      fireEvent = true;
    }

    //check to see if they are the same direction
    if (oldDelta > 0 && newDelta > 0) {

      //check to see if the new is higher
      if (oldDelta < newDelta) {
        fireEvent = true;
      } else {
        fireEvent = false;
      }
    }

    //check to see if they are the same direction
    if (oldDelta < 0 && newDelta < 0) {

      //check to see if the new is lower
      if (oldDelta > newDelta) {
        fireEvent = true;
      } else {
        fireEvent = false;
      }
    }

  } else {

    fireEvent = true;

  }

  oldDelta = newDelta;

} else {

  fireEvent = true;

}
Run Code Online (Sandbox Code Playgroud)

您可以在此处看到修复程序:https://sandbox.idev.ge/roomshotel/html5_v2/但它是一个命中/未命中.

Sam*_*kiy 10

具有超时的最新解决方案有一个主要缺点:动态滚动效果可能持续相当长(甚至1秒左右)......并且禁用滚动1-2秒并不是最佳决定.

Soooo,正如所承诺的,这是另一种方法.

我们的目标是为一个用户操作提供一个响应,在这种情况下是滚动.

什么是'滚动'?为了解决这个问题,让我们说'一次滚动'是一个从页面开始移动到移动结束的那一刻持续的事件.

通过将页面移动多次(例如,每20ms)一小段距离来实现动态滚动效果.这意味着我们的动力学滚动包含许多很小的线性"滚动".

经验测试表明,这种小"滚动"在动能滚动中间每17-18ms发生一次,在开始和结束时约为80-90ms.这是一个简单的测试我们可以设置来看到:

var oldD;
var f = function(){
    var d = new Date().getTime();
    if(typeof oldD !== 'undefined')
        console.log(d-oldD);
    oldD = d;
}
window.onscroll=f;
Run Code Online (Sandbox Code Playgroud)

重要!每次发生此小型滚动时,都会触发滚动事件.所以:

 window.onscroll = function(){console.log("i'm scrolling!")};
Run Code Online (Sandbox Code Playgroud)

在一次动力学滚动期间将被解雇15至20次.顺便说一句,onscroll有很好的浏览器支持(参见兼容性表),所以我们可以依赖它(触摸设备除外,我稍后会讨论这个问题);

有人可能会说重新定义window.onscroll不是设置事件侦听器的最佳方法.是的,我们鼓励你使用

 $(window).on('scroll',function(){...});
Run Code Online (Sandbox Code Playgroud)

或者你喜欢什么,这不是问题的关键(我个人使用我自己编写的库).

因此,在onscroll事件的帮助下,我们可以可靠地说出页面的这个特殊迷你运动是属于一个持久的动力学滚动,还是一个新的:

    var prevTime = new Date().getTime();
    var f = function(){
        var curTime = new Date().getTime();
        if(typeof prevTime !== 'undefined'){
            var timeDiff = curTime-prevTime;
            if(timeDiff>200)
                console.log('New kinetic scroll has started!');
        }
        prevTime = curTime;
    }
    window.onscroll=f;
Run Code Online (Sandbox Code Playgroud)

而不是"console.log",你可以调用你想要的回调函数(或事件处理程序),你就完成了!每次动能或简单滚动时,该功能只会触发一次,这是我们的目标.

您可能已经注意到我使用200ms作为新卷轴或前一卷轴的一部分的标准.您可以将其设置为更高的值,即999%,确保您可以阻止任何额外的呼叫.但是,请记住,这不是我之前的答案中使用的内容.它只是两个页面移动之间的一段时间(无论是新卷轴还是动态卷轴的一小部分).在我看来,在动能滚动的步骤之间存在超过200ms的滞后的可能性很小(否则它将根本不平滑).

正如我上面提到的,onscroll事件在触摸设备上的工作方式不同.在动能滚动的每一个小步骤中都不会发射.但是当页面的移动最终结束时它会触发.此外,还有ontouchmove活动......所以,这不是什么大不了的事.如有必要,我也可以为触摸设备提供解决方案.

PS我明白我写得太多了,所以我很乐意回答你的所有问题并提供更多代码,如果你需要的话.

所有浏览器都支持所提供的解决方案,非常轻量级,更重要的是,它不仅适用于mac,而且适用于可能实现动态滚动的每个设备,所以我认为这真的是一种方法.