8

コードが確実に呼び出されるように、mousemoveイベントを集約するクリーンな方法を見つけようとしていますが、250〜300ミリ秒に1回だけです。

私は次のようなものを使用することを考えましたが、より良いパターンがあるのか​​、それともjQueryが提供するもので同じことをするのか疑問に思いました:

var mousemove_timeout = null;

$('body').mousemove(function() {
  if (mousemove_timeout == null) {
    mousemove_timeout = window.setTimeout(myFunction, 250);
  }
});

function myFunction() {
  /*
   * Run my code...
   */

  mousemove_timeout = null;
}

編集:以下の受け入れられた回答はこの状況で完全にmousestop()機能しますが、回答で提供された機能によって実際に集計の必要がなくなったことがわかりました。したがって、この質問を読んで回答を探している場合は、マウスストップかどうかを確認してくださいプラグインはあなたが本当に必要なものです!

4

9 に答える 9

18

受け入れられた答えで解決策を試した後、特に円運動でマウスが絶えず動き続けると、mousemove()イベントが継続的に発生しますが、マウスの座標は同じままであることがわかりました。そこで、mousestop()とsetTimeoutを排除するより簡単なソリューションを思いつきました。

$("body").mousemove(function (e) {
        if (enableHandler) {
            handleMouseMove(e);
            enableHandler = false;
        }
});

timer = window.setInterval(function(){
    enableHandler = true;
}, 100);

これにより、約100ミリ秒ごとにhandleMouseMove()が正しく呼び出されます。(JavaScriptの時間遅延と間隔はリアルタイムで保証されていないため、おおよそ言ったことに注意してください)

于 2012-01-05T14:22:07.330 に答える
5

nullに設定する前にタイムアウトをクリアする必要があることを除いて、コードは問題ありません。そうしないと、リークが発生する可能性があります。

window.clearTimeout(mousemove_timeout);
mousemove_timeout = null;

別の方法として、 window.setIntervalと組み合わせてmousemove/ mousestopを使用できます。

var timer = null;
var isIntervalSet = false;

$('body').mousemove(function() {
    if (isIntervalSet) {
        return;
    }
    timer = window.setInterval(function() {
        /*
        * Run my code...
        */    
    }, 250);
    isIntervalSet = true;
}).mousestop(function() {
    isIntervalSet = false;
    window.clearTimeout(timer);
    timer = null;
});
于 2011-01-10T15:37:52.490 に答える
4

解決策と質問^^

グローバル変数なしのこのアプローチはどうですか。それは適切な解決策ですか?

$(function() {
    $("#foo").mousemove((function() {
        var timer = null;

        return function() {
            if (timer !== null) {
                window.clearTimeout(timer);
            }
            timer = window.setTimeout(foo, 250);
        };
    })());
});

function foo() {
    //...
}
于 2011-01-10T15:47:49.243 に答える
3

ミリ秒のカスタム期間でマウスの位置を取得する簡単な方法

var timer;
var refresh_time = 50;
var x = 0;
jQuery('body').mousemove(function(evt) {
  if (timer)
    clearTimeout(timer);
    timer = setTimeout(function(){
      var mouse_x = evt.clientX;
      if(mouse_x != x){
        x = mouse_x;
        console.log('mouse is on a new x position' + x);    
      }
    }, refresh_time);        
})
于 2013-02-23T20:20:54.380 に答える
2

あなたはコードスロットル/デバウンスを求めています。

http://benalman.com/projects/jquery-throttle-debounce-plugin/ http://drupalmotion.com/article/debounce-and-throttle-visual-explanation

underscore.jSからのサンプル

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
于 2015-09-10T13:25:23.090 に答える
2

パーティーに少し遅れていることは知っていますが、このスレッドにアクセスする人には役立つかもしれません。これが私の2セントです。

モジュラス演算子と単純な数値の増分を使用すると、次のように、パフォーマンスへの影響を最小限に抑えて関数の発火率を調整できます。

var fired = 0;
$('#element').on('mousemove', function(){
   fired++;
   // Fire 5x less than usual
   if(!(fired % 5) || fired == 1) yourFunction();
})

さらに、最大整数制限に達することを恐れている場合は、X千ヒットごとに(ここでもモジュラス演算子を使用して)、またはmouseoutイベントを使用して、起動された変数をリセットできます。

于 2015-12-30T14:38:12.330 に答える
1

これは本当に興味深い質問でした。私はこれを行うためのよりハックな方法を見つけました、そしてあなたは次のスニペットのこのライブデモをチェックすることができます:

({
    event: null,
    interval: null,
    init: function(){
        var self = this;
        $(document).bind("mousemove", function(e){self.event=e;});
        this.interval = setInterval(function(){
            /** do what you wish **/
            console.log(self.event);
        }, 250);
        return this;
    },
    stop: function(){
        $(document).unbind("mousemove", this.event);
        clearInterval(this.interval);
    },
}).init();
于 2011-01-10T16:13:53.550 に答える
1

タイムアウトを使用してタイマーをヌルにすることにより、数行を節約できます。

var paused = null;

$("body").mousemove(function (e) {
    if (!paused){
        /** your code here **/
        paused = setTimeout(function(){paused=null}, 250);
    }
});
于 2012-08-17T17:47:08.833 に答える
0

タイムアウトの代わりにsetInterval()を使用してみませんか?

于 2011-01-10T15:51:20.303 に答える