2011-01-10 15 views
7

mousemoveイベントを集約して、コードが確実に呼び出されるようにするには、250〜300ミリ秒ごとに1回しか実行しないでください。jQuery:mousemoveイベントを頻繁に発生させない

私は、次のようなものを使用してについて考えてきましたが、より良いパターン、または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; 
} 

EDIT:受け入れ答えしかし、この状況では完全に機能するはずですが、答えに含まれるmousestop()機能が実際に集計の必要性をなくしていることがわかりました。この質問を読んで答えを探しているのなら、mousestopプラグインが本当に必要!

答えて

5

あなたのコードは、それがnullにまたはそれが漏れる可能性がある設定する前にclear the timeoutあなたがすべきことを除いて結構です。あなたはwindow.setInterval

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; 
}); 
+0

+1 - チップをありがとう!これは最高です/清潔な方法ですか?ハックのビットのようです... –

+1

確かにそれは少しのハックです、 'window.setInterval'はこのシナリオにもっと適合します。 –

+0

受け入れられる! - 'mousestop'関数は私が必要とするものであり、タイムアウトコードを完全になくします。本当にありがとう! –

4

と併せてのMouseMove/mousestopを使用することができます別の方法として

window.clearTimeout(mousemove_timeout); 
mousemove_timeout = null; 

解決策と質問^^

グローバルなvarがないこのアプローチについてはどうでしょうか?それは適切な解決策ですか?

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

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

function foo() { 
    //... 
} 
+1

+1 - 私は間違いなくグローバル変数を使用したくありません。私はこのコードを試していませんが、かなりクリーンで直感的です。 –

+0

+1ベストソリューション – algorhythm

1

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

({ 
    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(); 
16

私は受け入れ答えで解決策を試した後、私はマウスを続ける場合は、常に動いていることが分かりました特に円運動では、mousemove()イベントは連続的に発生しますが、マウス座標は同じままです。 私はmousestop()とsetTimeoutを排除する簡単な解決法を考え出しました。

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

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

これは、およそ100msごとにhandleMouseMove()を正しく呼び出します。

var paused = null; 

$("body").mousemove(function (e) { 
    if (!paused){ 
     /** your code here **/ 
     paused = setTimeout(function(){paused=null}, 250); 
    } 
}); 
+1

+1 - ありがとう!これは実際に私が最初に探していたソリューションのタイプです。これは受け入れられた答えよりはるかにクリーンなアプローチですが、mousestopプラグインはまだ私が行ったものです。 –

+0

マウスが動いていないときにタイマーを停止する方法はありますか? – interstellarDust

1

(JavaScriptで時間遅延との間隔が保証され、リアルタイムではありませんので、私は約言っていることに注意してください)ミリ秒のカスタム期間にマウスの位置を取得する

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);   
}) 
3

簡単な方法の:あなたは、タイマーをゼロにするために、タイムアウトを使って、数行を保存することができます

2

あなたはコードのスロットリング/デバウンスを求めます。

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

アンダースコアからのサンプル。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); 
    }; 
}; 
1

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

モジュラス演算子と単純な増分を使用すると、パフォーマンスの低下を最小限に抑えて関数の実行率を抑えることができます。あなたが最大の整数の制限をヒットすることを恐れている場合

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

また、あなたはすべてのX千安打(再び、剰余演算子を使用して)、またはマウスアウトイベントを用いて焼成変数をリセットすることができます。

関連する問題