jQuery:firemousemove事件较少发生

jQuery:firemousemove事件较少发生,jquery,settimeout,mousemove,Jquery,Settimeout,Mousemove,我正试图找出一种干净的方法来聚合mousemove事件,这样我就可以确保我的代码被调用,但只能每250-300毫秒调用一次 我曾考虑过使用类似于以下的方法,但我想知道是否有更好的模式,或者jQuery提供的方法可以做同样的事情: var mousemove_timeout = null; $('body').mousemove(function() { if (mousemove_timeout == null) { mousemove_timeout = window.setTi

我正试图找出一种干净的方法来聚合mousemove事件,这样我就可以确保我的代码被调用,但只能每250-300毫秒调用一次

我曾考虑过使用类似于以下的方法,但我想知道是否有更好的模式,或者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()
功能实际上消除了我对聚合的需求,因此如果您正在阅读此问题并寻找答案,请查看插件是否是您真正需要的

您的代码很好,只是在将其设置为null之前应该执行以下操作,否则可能会泄漏:

window.clearTimeout(mousemove_timeout);
mousemove_timeout = null;
或者,您可以将mousemove/与


解决方案和问题^^

这种没有全局var的方法怎么样?这是合适的解决方案吗

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

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

function foo() {
    //...
}

为什么不使用超时来代替呢?

这是一个非常有趣的问题。我找到了一种不那么粗俗的方法来实现这一点,您可以从以下代码片段中查看这一点:

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

在我尝试了公认答案中的解决方案后,我发现如果鼠标不断移动,特别是在圆周运动中,mousemove()事件会不断触发,但鼠标坐标保持不变。 所以我想出了一个更简单的解决方案,它消除了mousestop()和setTimeout

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

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

这将大约每100ms正确调用handleMouseMove()。(请注意,我所说的大概是因为JavaScript中的时间延迟和间隔不是实时保证的)

您可以通过使用超时使计时器为空来节省几行:

var paused = null;

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

一种在自定义毫秒周期内获取鼠标位置的简单方法

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

您寻求代码节流/去抖动

来自下划线.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);
    };
};

我知道我参加聚会有点晚了,但这可能对访问此帖子的人有用,这是我的2美分

使用模运算符和简单的数字增量,您可以在性能影响最小的情况下限制函数的触发速率,如下所示

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

此外,如果您害怕达到最大整数限制,您可以每X千次点击(再次使用模数运算符)或使用mouseout事件重置激发变量。

+1-感谢您的提示!这是最好/最干净的方式吗?看起来有点像黑客……是的,确实有点像黑客,
window.setInterval
更适合这种情况。接受!-事实证明,
mousestop
函数正是我所需要的,它将完全消除超时代码。非常感谢!这种方法有点不对劲:如果鼠标不断移动,mousemove事件不断被触发,但鼠标坐标保持不变。+1-谢谢!这实际上是我最初寻找的解决方案类型。这是一个比公认的答案更简洁的方法,但是,mousestop插件仍然是我使用的。当鼠标不移动时,有没有办法停止计时器?+1-我绝对不喜欢使用全局变量。虽然我还没有尝试过这段代码,但它看起来确实相当干净和直观。
var fired = 0;
$('#element').on('mousemove', function(){
   fired++;
   // Fire 5x less than usual
   if(!(fired % 5) || fired == 1) yourFunction();
})