【问题标题】:Jquery, unbinding mousewheel event, then rebinding it after actions are completed?Jquery,取消绑定鼠标滚轮事件,然后在动作完成后重新绑定它?
【发布时间】:2010-07-26 19:40:27
【问题描述】:

我已经为此苦苦挣扎了一段时间.. 我正在使用此代码来监视鼠标滚轮,因此它可以用于使用我拥有的滑块进行滚动.. 但是,它的操作存在问题排队,所以如果你用鼠标滚轮快速滚动(就像任何人通常会做的那样),它们会堆积起来,这会导致错误的行为。我知道用动画处理这类问题,但用鼠标滚轮监视器不知道。..

我想在动作开始时取消绑定鼠标滚轮(在这种情况下,移动鼠标滚轮后滚动滚动条)然后在此之后重新绑定它,所以如果用户滚动太多太快它只是忽略直到初始滚动完成。我尝试了下面的代码,但它没有重新绑定,所以我不确定我做错了什么,感谢任何建议。

        $("#wavetextcontainer").bind("mousewheel", function(event, delta) {

   //HERE IS WHERE EVENT IS UNBOUND:
     $("#wavetextcontainer").unbind("mousewheel");

        var speed = 10;
        var mySlider = $("#slider");
        var sliderVal = mySlider.slider("option", "value");

        sliderVal += (delta*speed);

        if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max");
        else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min");

        $("#slider").slider("value", sliderVal);

        event.preventDefault();

      // HERE I WANT TO REBIND THE EVENT:
     $("#wavetextcontainer").bind("mousewheel");

});

【问题讨论】:

    标签: jquery mousewheel unbind


    【解决方案1】:

    如果您可以引用它,您需要存储该函数,如下所示:

    function myHandler(event, delta) {
         $("#wavetextcontainer").unbind("mousewheel", myHandler);
    
            var speed = 10;
            var mySlider = $("#slider");
            var sliderVal = mySlider.slider("option", "value");
    
            sliderVal += (delta*speed);
    
            if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max");
            else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min");
    
            $("#slider").slider("value", sliderVal);
    
            event.preventDefault();
    
          // HERE I WANT TO REBIND THE EVENT:
         $("#wavetextcontainer").bind("mousewheel", myHandler);    
    };
    
    $("#wavetextcontainer").bind("mousewheel", myHandler);
    

    通过这样做,您可以稍后将.bind() 调用到同一个函数(您不能引用匿名函数)。您当前正在尝试调用.bind() 没有 一个函数来处理任何事情,但这是行不通的。这还具有额外的优势,即能够将相同的函数引用传递给.unbind(),因此它解除绑定该处理程序,而不是任何 mousewheel处理程序。


    或者,这样做没有取消/重新绑定,像这样:

    $("#wavetextcontainer").bind("mousewheel", function (event, delta) {
      event.preventDefault();
      if($.data(this, 'processing')) return; //we're processing, ignore event
    
      $.data(this, 'processing', true);
      var speed = 10;
      var mySlider = $("#slider");
      var sliderVal = mySlider.slider("option", "value");
    
      sliderVal += (delta*speed);
    
      if (sliderVal > mySlider.slider("option", "max")) sliderVal = mySlider.slider("option", "max");
      else if (sliderVal < mySlider.slider("option", "min")) sliderVal = mySlider.slider("option", "min");
    
      $("#slider").slider("value", sliderVal);
      $.data(this, 'processing', false);
    });
    

    这只是使用$.data() 来存储带有元素的“我们正在工作”数据条目,如果有任何东西在它为真时命中了这个处理程序,它只会返回并忽略该事件。

    【讨论】:

    • 我现在明白了.. 匿名函数是我一直在努力解决的问题,因为它在我以前使用的其他语言中不存在.. 这有助于我清除它,谢谢
    • @Rick - 欢迎 :) 我添加了另一个替代方案,可以为您进一步简化事情,试一试。
    • 我认为第二个答案可能会更好,因为解绑工作,就解绑/重新绑定而言,但它仍然给人一些奇怪的感觉,似乎是对事件的排队
    【解决方案2】:

    在这种情况下,有很多不必要的绑定/解除绑定,这比必须做的更困难、效率更低。当不再需要某个操作或暂时不需要某个操作时,解除绑定非常适合释放资源;但是对于不希望您的代码运行取消绑定/重新绑定的瞬间来说,开销很大,只需使用一个变量来确定是否支持鼠标滚轮,并根据需要切换它的真假。可能也不需要使用 jquery 数据,只需在函数外部定义一个更快的 var。

    var doMouseWheel = true;
    $("#wavetextcontainer").bind("mousewheel", function(event, delta)
    {
            // it'll just not do anything while it's false
            if (!doMouseWheel)
                return;
    
            // here's where you were unbinding, now just turning false
            doMouseWheel = false;
    
            // do whatever else you wanted
    
            // here's where you were rebinding, now just turn true
            doMouseWheel = true;
    });
    

    虽然老实说,仅在上面的几行进程中禁用滚动条的逻辑有点缺陷,但您必须是一个经常处理多线程语言的程序员 :) 在 js 中,甚至不可能触发另一个事件函数代码行的中间,所以我假设您宁愿将其关闭一段时间(无论您使用变量还是绑定/取消绑定都适用):

    var doMouseWheel = true;
    $("#wavetextcontainer").bind("mousewheel", function(event, delta)
    {
            // it'll just not do anything while it's false
            if (!doMouseWheel)
                return;
    
            // here's where you were unbinding, now just turning false
            doMouseWheel = false;
    
            // do whatever else you wanted
    
            // here's where you were rebinding, now wait 200ms and turn on
            setTimeout(turnWheelBackOn, 200);
    });
    
    function turnWheelBackOn() { doMouseWheel = true; }
    

    【讨论】:

    • 非常感谢! @Jimbo我正在尝试自己构建它,但绑定并没有停止传播。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    相关资源
    最近更新 更多