Jquery, отменяет привязку события mousewheel, а затем повторно связывает его после завершения действий? - PullRequest
8 голосов
/ 26 июля 2010

Я уже некоторое время борюсь с этим .. Я использую этот код для мониторинга колесика мыши, чтобы его можно было использовать для прокрутки с помощью ползунка, который у меня есть ... однако у него есть проблема, когда действияставьте в очередь, поэтому, если вы прокручиваете колесо мыши быстро (как это обычно делают все), они накапливаются, и это вызывает некорректное поведение. Я знаю об обработке такого рода проблем с анимацией, но не с монитором колеса мыши.

Я хочу сделать что-то вроде отсоединения колесика мыши в начале действия (в данном случае, чтобы прокрутить полосу прокрутки после перемещения колесика мыши), затем перепривязать ее после этого, поэтому, если пользователь делает слишком много прокруток слишком быстро, он просто игнорируетначальная прокрутка завершена .. Я попробовал приведенный ниже код, но он не связывается, поэтому я не уверен, что делаю неправильно, любой совет приветствуется.

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

7 голосов
/ 26 июля 2010

Вам нужно сохранить функцию, на которую вы можете ссылаться, например:

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(), поэтому она отменяет привязку only к этому обработчику, а не any 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() для хранения записи данных "мы работаем" с элементом, если что-то попадает в этот обработчик, пока оно истинно, оно просто возвращает и игнорирует событие.

5 голосов
/ 20 апреля 2012

В этой ситуации очень много ненужных привязок / откреплений, что сложнее и неэффективно, чем должно быть. Отмена привязки - это замечательно для освобождения ресурсов, когда действие больше не нужно или какое-то время не понадобится; но на долю секунды нежелание выполнения кода отмены привязки / перепривязки является большой нагрузкой, просто используйте переменную, чтобы определить, следует ли указывать колесо мыши или нет, и просто переключайте его как true и false по мере необходимости. Скорее всего, нет необходимости использовать данные jquery, просто более быстрая переменная, определенная вне функции.

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 даже невозможно запустить другое событие в посередине строк кода функции, поэтому я предполагаю, что вы предпочли бы отключить ее на некоторое время (и это будет применяться независимо от того, используете ли вы переменную или bind / unbind):

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; }
...