Jquery,取消绑定mousewheel事件,然后在操作完成后重新绑定它?

时间:2010-07-26 19:40:28

标签: jquery mousewheel unbind

我一直在努力解决这个问题。我正在使用此代码来监控鼠标滚轮,因此它可以用于我使用的滑块进行滚动..但是,它有一个问题所在的行动排队所以如果你用鼠标滚动快速滚动(就像任何人会正常做的那样)他们会积累并导致错误的行为..我知道用动画处理这类问题,但不是用鼠标滚轮监视器..

我想做一些事情,比如在动作开始时取消绑定鼠标滚轮(在这种情况下,在移动鼠标滚轮后滚动滚动条)然后在此之后重新绑定它,所以如果用户执行的滚动太多太快就会忽略它直到最初的滚动完成..我尝试了下面的代码,但它没有重新绑定所以我不确定我做错了什么,任何建议都表示赞赏。

        $("#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");

});

2 个答案:

答案 0 :(得分:7)

你需要存储功能,你可以参考它,像这样:

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()来存储一个“我们正在工作”的数据条目与元素,如果有任何东西击中这个处理程序,它是真的,它只返回并忽略该事件。

答案 1 :(得分:5)

在这种情况下,存在许多不必要的绑定/解除绑定,这比它必须更加困难和更低效。取消绑定对于在不再需要某个操作时释放资源很有用,或者暂时不需要;但是对于不希望你的代码运行解除绑定/重新绑定的瞬间是很多开销,只需使用变量来确定是否遵守鼠标滚轮,并根据需要将其切换为true和false。可能也不需要使用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; }