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()、要素を含む「作業中」のデータエントリを格納するために使用されます。trueのときにこのハンドラーに何かがヒットすると、イベントが返され、無視されます。

于 2010-07-26T19:45:13.713 に答える
5

この状況では、これは多くの不要なバインド/バインド解除であり、必要以上に困難で非効率的です。バインド解除は、アクションが不要になった場合、またはしばらくの間必要にならない場合にリソースを解放するのに最適です。ただし、コードのバインド解除/再バインドを実行したくない場合は、かなりのオーバーヘッドが発生します。変数を使用して、マウスホイールを尊重するかどうかを決定し、必要に応じて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では、別のイベントが途中で発生することさえありません。関数のコード行なので、しばらくの間それをシャットオフしたいと思います(そして、それは変数を使用するかバインド/アンバインドするかに関係なく適用されます):

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 に答える