2011-01-10 4 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해야이 null로하거나 누설 할 수 설정하기 전에 :

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

약 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

(자바 스크립트에서 시간 지연과 간격을 보장 실시간 아니기 때문에 내가 약 말했다 있습니다) miliseconds의 사용자 지정 기간에 마우스 위치를 얻으십시오.

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

간단한 방법 : 당신은 타이머를 null로 타임 아웃을 사용하여 몇 줄을 절약 할 수 있습니다

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 천 안타를 재설정하거나 mouseOut 이벤트를 사용하여 할 수 있습니다.

관련 문제