我正在尝试找出一种简洁的聚合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插件是否真的需要你!
答案 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 / mousestop与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;
});
答案 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()而不是超时?