【问题标题】:jquery mousewheel: detecting when the wheel stops?jquery mousewheel:检测滚轮何时停止?
【发布时间】:2011-03-31 17:39:42
【问题描述】:

我正在使用 Jquery mousewheel 插件,我希望能够检测到用户何时完成使用滚轮。 与 stop: 可拖动内容中的事件类似的功能。 有人能指出我正确的方向吗?

【问题讨论】:

    标签: jquery event-handling mousewheel


    【解决方案1】:

    这里真的没有“停止”事件——当你滚动时你会得到一个事件,所以每次鼠标滚轮事件发生时都会触发事件......当什么都没有时你会得到没有事件和你的处理程序不会被触发。

    但是,您可以检测到用户在 250 毫秒内没有使用它的时间,如下所示:

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

    You can give it a try here,我们所做的只是在使用$.data() 时存储每次使用的超时时间,如果您在该时间用完之前再次使用它,它会被清除...如果不是,那么您想要的任何代码运行火灾,用户已经“完成”了使用鼠标滚轮的任何时间段。

    【讨论】:

    • 是的,我正在考虑类似的事情。我会试一试。非常感谢尼克。
    • @Moustard - 欢迎 :) 如果成功,请务必接受您的问题的答案 ;)
    • 不适用于 Apple 笔记本电脑或 Magic 鼠标中的动态滚动。
    【解决方案2】:

    完成尼克·克拉弗的回答:

    var wheeldelta = {
      x: 0,
      y: 0
    };
    var wheeling;
    $('#foo').on('mousewheel', function (e) {
      if (!wheeling) {
        console.log('start wheeling!');
      }
    
      clearTimeout(wheeling);
      wheeling = setTimeout(function() {
        console.log('stop wheeling!');
        wheeling = undefined;
    
        // reset wheeldelta
        wheeldelta.x = 0;
        wheeldelta.y = 0;
      }, 250);
    
      wheeldelta.x += e.deltaFactor * e.deltaX;
      wheeldelta.y += e.deltaFactor * e.deltaY;
      console.log(wheeldelta);
    });
    

    滚动输出:

    start wheeling!
    Object {x: -1, y: 0}
    Object {x: -36, y: 12}
    Object {x: -45, y: 12}
    Object {x: -63, y: 12}
    Object {x: -72, y: 12}
    Object {x: -80, y: 12}
    Object {x: -89, y: 12}
    Object {x: -97, y: 12}
    Object {x: -104, y: 12}
    Object {x: -111, y: 12}
    Object {x: -117, y: 12}
    Object {x: -122, y: 12}
    Object {x: -127, y: 12}
    Object {x: -131, y: 12}
    Object {x: -135, y: 12}
    Object {x: -139, y: 12}
    Object {x: -145, y: 12}
    Object {x: -148, y: 12}
    Object {x: -152, y: 12}
    Object {x: -154, y: 12}
    Object {x: -156, y: 12}
    Object {x: -157, y: 12}
    Object {x: -158, y: 12}
    Object {x: -159, y: 12}
    Object {x: -161, y: 12}
    Object {x: -162, y: 12}
    Object {x: -164, y: 12}
    Object {x: -166, y: 12}
    Object {x: -167, y: 12}
    Object {x: -169, y: 12}
    stop wheeling!
    

    【讨论】:

      【解决方案3】:

      以下是在原生 JavaScript 中的操作方法:

      var _scrollTimeout = null;
      
      function onMouseWheel() {
          var d = ((typeof e.wheelDelta != "undefined") ? (-e.wheelDelta) : e.detail);
          d = 100 * ((d>0)?1:-1);
      
          console.log("Scroll delta", d);
      
          clearTimeout(_scrollTimeout);
          _scrollTimeout = setTimeout(function() {
              console.log("Haven't scrolled in 250ms");
          }, 250);
      }
      
      window.addEventListener( 'mousewheel', onMouseWheel, false );
      window.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
      

      【讨论】:

        【解决方案4】:

        以下是实现您自己的车轮停止事件的方法。

        //initialise the new variables
        var wheelMap = new Map;
        var deltaXEnded = false;
        var deltaYEnded = false;
        var previousSwipe = Object;
            previousSwipe.timeStamp = 0;
            previousSwipe.deltaX = 0;
            previousSwipe.deltaY = 0;
        var wheelstart = false;
        

        wheelstop 事件创建一个新的 eventListener

        我们将从 normalWheelEventCallbackFunction()

        调用它
        var wheelstop = new Event("wheelstop");
        

        接下来,我们将定义在此事件被调度的情况下的回调,然后将事件添加到窗口对象。

        function wheelstopcallback(event){
            wheelstart = false;
            console.log("wheel event has ended");
        }
        window.addEventListener("wheelstop", wheelstopcallback.bind(this));
        

        现在我们定义正常的车轮事件监听器以及定义这个监听器将使用的回调......

        window.addEventListener("wheel", normalWheelEventCallbackFunction.bind(this));
        

        Wheel事件回调函数

        function normalWheelEventCallbackFunction(event){
           if(previousSwipe.timeStamp !== 0){
              if(event.timeStamp - previousSwipe.timeStamp < 1000)
                 wheelMap.set(event.timeStamp, event);
              else
                 wheelMap.clear();
           }
         else{previousSwipe.timeStamp = event.timeStamp;}
        
        
          if(event.deltaX > 2 && event.deltaX > previousSwipe.deltaX){
             //forward
             wheelstart = true
          }
          else if(event.deltaX < -2&& event.deltaX < previousSwipe.deltaX){
             //backward
             wheelstart = true;
          }
          else if(event.deltaY > 2 && event.deltaY > previousSwipe.deltaY){
             wheelstart = true;
          }
          else if(event.deltaY < 2 && event.deltaY < previousSwipe.deltaY){
             wheelstart = true;
          }
          
          if(
             ((event.deltaX === 1 || event.deltaX === 0 || event.deltaX === -1) && ((event.deltaX > 0 && event.deltaX < previousSwipe.deltaX) || (event.deltaX < 0 && event.deltaX > previousSwipe.deltaX)) && wheelstart)
             || (wheelstart && (event.deltaX === 0 && previousSwipe.deltaX === 0))
          )
          {
             deltaXEnded = true;
             console.log("deltaXEnded");
          }
          if(
             (((event.deltaY === 1 || event.deltaY === 0 || event.deltaY === -1) && ((event.deltaY > 0 && event.deltaY < previousSwipe.deltaY) || (event.deltaY < 0 && event.deltaY > previousSwipe.deltaY))) && wheelstart)
             || (wheelstart && (event.deltaY === 0 && previousSwipe.deltaY === 0)))     {
                deltaYEnded = true;
                console.log("deltaYEnded");
             }
          
             if(deltaXEnded && deltaYEnded){
                deltaXEnded = false;
                deltaYEnded = false;
                window.dispatchEvent(wheelstop);
             }
        
          previousSwipe.deltaX = event.deltaX;
          previousSwipe.deltaY = event.deltaY;
        }
        

        这可能有一些错误,但在大多数情况下,逻辑是相当合理的,我会推荐一个后备,但是如果你需要捕获每一个调度的车轮事件,因为它可能在 'wheelstop' 事件之后有一些已发送。

        哦,最后确定并实现一个处理程序,以处理它是否被点击事件中断,从而结束滚轮事件......

        function wheelstopdispatch(){
          if(wheelstart)
            window.dispatchEvent(wheelstop);
          }
        window.addEventListener("click", wheelstopdispatch);
        

        【讨论】:

          【解决方案5】:

          Nick Craver 的 answer 工作正常。但它会导致执行// do something 的小延迟(250 毫秒)。更好的选择是立即执行您的代码并等待delayms,然后再捕获更多事件。

          为此,请使用全局变量 processing,使用 false 对其进行初始化,并在代码执行前后切换其值。

          window.processing = false;
          $("#myElem").mousewheel(function() {
             if (processing === false) {
               processing = true;
               // do something
               setTimeout(function() {
                 processing = false;
               }, 250)); // waiting 250ms to change back to false.
             }
           });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-03-01
            • 2012-02-27
            • 2012-07-08
            • 2012-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-24
            相关资源
            最近更新 更多