8

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

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

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

});
4

2 回答 2

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()与元素一起存储“我们正在工作”数据条目,如果有任何事情在它为真时命中此处理程序,它只会返回并忽略该事件。

于 2010-07-26T19:45:13.713 回答
5

在这种情况下,有很多不必要的绑定/解除绑定,这比必须的更困难、效率更低。当不再需要某个操作或暂时不需要某个操作时,解除绑定非常适合释放资源;但是对于不希望您的代码运行取消绑定/重新绑定的瞬间来说,开销很大,只需使用一个变量来确定是否支持鼠标滚轮,并根据需要切换它的真假。可能也不需要使用 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; }
于 2012-04-19T20:59:57.913 回答