2011-01-10 13 views
7

मैं mousemove घटनाओं को कुल करने के लिए एक साफ तरीका पता लगाने की कोशिश कर रहा हूँ ताकि मैं सुनिश्चित कर सकूं कि मेरा कोड बुलाया जाता है, लेकिन केवल 250-300 मिलीसेकंड में एक बार।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; 
} 

संपादित करें: स्वीकार किए जाते हैं जवाब नीचे इस स्थिति के लिए पूरी तरह से काम करेगा, हालांकि, मैंने पाया कि उत्तर में प्रदान की गई mousestop() कार्यक्षमता ने वास्तव में एकत्रीकरण की मेरी आवश्यकता को समाप्त कर दिया है, इसलिए यदि आप इस प्रश्न को पढ़ रहे हैं और उत्तर ढूंढ रहे हैं, तो देखें कि mousestop प्लगइन क्या है वास्तव में जरुरत है!

उत्तर

5

आपका कोड को छोड़कर ठीक है कि आप चाहिए clear the timeout यह शून्य पर या यह रिसाव हो सकता है सेट करने से पहले:

window.clearTimeout(mousemove_timeout); 
mousemove_timeout = null; 

एक विकल्प के आप 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 इस्तेमाल कर सकते हैं के रूप में एक समाधान और एक प्रश्न ^^

वैश्विक वैर के बिना इस दृष्टिकोण के बारे में क्या। क्या यह एक उपयुक्त समाधान है?

$(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

यह वास्तव में एक दिलचस्प सवाल था। मैं इस पर करने के लिए एक कम hackish रास्ता मिल गया है, और आप निम्नलिखित स्निपेट के इस 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); 

यह लगभग 100msms handleMouseMove() को सही ढंग से कॉल करेगा। (ध्यान दें कि मैं लगभग कहा क्योंकि समय देरी और जावास्क्रिप्ट में अंतराल वास्तविक समय इसकी गारंटी नहीं है)

+1

+1 - धन्यवाद! यह वास्तव में समाधान का प्रकार है जिसे मैं मूल रूप से ढूंढ रहा था। स्वीकार्य उत्तर से यह एक बहुत साफ दृष्टिकोण है, लेकिन, mousestop प्लगइन अभी भी मैं साथ गया था। –

+0

क्या माउस चल रहा है जब टाइमर को रोकने का कोई तरीका है? – interstellarDust

1

आप टाइमर शून्य पर टाइमआउट का उपयोग करके कुछ लाइनें बचा सकते हैं:

var paused = null; 

$("body").mousemove(function (e) { 
    if (!paused){ 
     /** your code here **/ 
     paused = setTimeout(function(){paused=null}, 250); 
    } 
}); 
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);   
}) 
2

आप कोड थ्रॉटलिंग/डिबॉन्सेसिंग कोड चाहते हैं।

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

अंडरस्कोर से नमूना।जेएस

// 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(); 
}) 

ही, यदि आप अधिकतम पूर्णांक सीमा हिट करने के लिए डर रहे हैं, तो आप निकाल दिया चर हर एक्स हजार हिट mouseout घटना का उपयोग करके रीसेट (फिर से, मापांक ऑपरेटर का उपयोग) कर सकते हैं या।

संबंधित मुद्दे