jQuery:不常用火鼠移动事件

时间:2011-01-10 15:35:52

标签: jquery settimeout mousemove

我正在尝试找出一种简洁的聚合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()功能实际上消除了我对聚合的需求,所以如果你正在阅读这个问题并寻找答案,看看mousestop插件是否真的需要你!

8 个答案:

答案 0 :(得分:16)

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

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

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

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

答案 1 :(得分:5)

您的代码很好,除非您在将其设置为null之前应该clear the timeout,否则它可能会泄漏:

window.clearTimeout(mousemove_timeout);
mousemove_timeout = null;

作为替代方案,您可以将mousemove / mousestopwindow.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;
});

答案 2 :(得分:4)

解决方案和问题^^

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

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

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

function foo() {
    //...
}

答案 3 :(得分: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);        
})

答案 4 :(得分:2)

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

使用模数运算符和简单的数字增量,您可以以最小的性能命中来限制函数的点火率,就像这样;

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

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

答案 5 :(得分: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();

答案 6 :(得分:1)

您可以使用超时来保存几行,以使计时器为空:

var paused = null;

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

答案 7 :(得分:0)

为什么不使用setInterval()而不是超时?