将mousemove事件限制为每秒触发不超过5次

Throttling a mousemove event to fire no more than 5 times a second

本文关键字:不超过 5次 mousemove 事件      更新时间:2023-09-26

我有一个绑定到mousemove处理程序的事件处理程序,它将通过console.log()记录当前鼠标位置。我的目标是每秒触发事件不超过5次,以防止每次移动鼠标时被淹没。

目前,我有下面的代码,它记录鼠标每次移动的位置,没有限制它,我似乎不知道出了什么问题

//Code runs after document is ready
function logMouse(event){
    console.log('The mouse is currently at ('+event.pageX+','+event.pageY+')');
  }
  $(document).on('mousemove',function(event){
    setTimeout(function(){
      logMouse(event);
    },200);
  });  

我正试图通过使用setTimeout来限制mousemove事件,并将计时器设置为200毫秒,这样它就会在1秒内触发5次,但我的代码不起作用,目前每当我移动鼠标时,只会给我大量的鼠标位置。

如何限制鼠标移动,使其每秒记录鼠标位置的次数不超过5次?

添加一个变量来跟踪事件刚刚发生的时间,并在允许下一个事件之前与setTimeout一起休眠。

var timesPerSecond = 5; // how many times to fire the event per second
var wait = false;
$(document).on('mousemove', function (event) {
    // don't handle events when one has just occurred
    if (!wait) {
        // fire the event
        logMouse(event);
        // stop any further events
        wait = true;
        // after a fraction of a second, allow events again
        setTimeout(function () {
            wait = false;
        }, 1000 / timesPerSecond);
    } 
});

或者,您可以避开setTimeout,只跟踪事件发生的最新时间。

var timesPerSecond = 5; // how many times to fire the event per second
var waitUntil = 0;
$(document).on('mousemove', function (event) {
    // don't handle events when one has just occurred
    if (Date.now() >= waitUntil) {
        // fire the event
        logMouse(event);
        // stop any further events for a moment
        waitUntil = Date.now() + 1000 / timesPerSecond;
    } 
});

我在整个项目中都使用这个包装器函数。不幸的是,在写这篇文章的时候,我不知道throttling这个恰当的术语。

// ignore fast events, good for capturing double click
// @param (callback): function to be run when done
// @param (delay): integer in milliseconds
// @param (id): string value of a unique event id
// @doc (event.timeStamp): http://api.jquery.com/event.timeStamp/
// @bug (event.currentTime): https://bugzilla.mozilla.org/show_bug.cgi?id=238041
ignoredEvent: (function () {
    var last = {},
        diff, time;
    return function (callback, delay, id) {
        time = (new Date).getTime();
        id = id || 'ignored event';
        diff = last[id] ? time - last[id] : time;
        if (diff > delay) {
            last[id] = time;
            callback();
        }
    };
})(),

你可以这样使用它:

$(document).on('mousemove',function(event){
    ignoredEvent(function(){
        logMouse(event);
    }, 200, 'mouse-move');
});