如何使用鼠标事件只在用户空闲X秒时进行AJAX调用

How to use mouse event to do AJAX call only if user is idle for X seconds

本文关键字:调用 AJAX 鼠标 何使用 事件 用户      更新时间:2023-09-26

如果这是转发,我们深表歉意。我见过很多例子。但我似乎无法满足我的需求。我有一个"今日"页面,显示所有群组。一天中会出现越来越多的小组。如果用户打开了页面并且已经X秒没有移动鼠标,我希望能够动态更新这些组。我有一大块代码:

var timeout = null;
    j$(document).on('mousemove', function() {
        if (timeout !== null) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
            timeout = null;
            //calls another page to check if there's new data to display. if so, wipe existing data and update
            j$.ajax({
                  url: "/include/new_Groups.php",
                  cache: false,
                  success: function(data){
                      j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
                  }
                })
                  .done(function( html ) {
              });
        }, 3000);
    });

这样做的目的是,如果用户在3秒钟后没有移动鼠标,则执行AJAX调用来更新组。这个半成品。如果你不移动鼠标,它会更新。但除非鼠标再次移动并闲置3秒,否则它不会再次更新,这不是很好的用户体验。

我正试图找到一种方法,如果用户空闲,只需每3秒(对于本例)持续更新一次页面。但如果他在移动鼠标,就不会有更新。如果我不清楚,请提问!提前谢谢。

应该是straigh-forward,使用间隔和函数调用代替

jQuery(function($) {
    var timer;
    $(window).on('mousemove', function() {
        clearInterval(timer);
        timer = setInterval(update, 3000);
    }).trigger('mousemove');
    function update() {
        $.ajax({
            url    : "/include/new_Groups.php",
        }).done(function (html) {
            $(".group_Container_Main").append(html).fadeIn('slow')
        });
    }
});

FIDDLE

编辑:

为了解决堆叠ajax请求的问题,如果由于某种原因,它们需要超过三秒才能完成,我们可以在开始新的ajax调用之前检查上一次ajax调用的状态,如果状态为pending,它仍在运行。

jQuery(function($) {
    var timer, xhr;
    $(window).on('mousemove', function() {
        clearInterval(timer);
        timer = setInterval(update, 1000);
    }).trigger('mousemove');
    function update() {
        if ( ! (xhr && xhr.state && xhr.state == 'pending' ) ) {
            xhr = $.ajax({
                url    : "/include/new_Groups.php",
            }).done(function (html) {
                $(".group_Container_Main").append(data).fadeIn('slow')
            });
        }
    }
});

在AJAX参数上,使用complete选项触发鼠标移动:

j$(document).on('mousemove', function() {
    if (timeout !== null) {
        clearTimeout(timeout);
    }
    timeout = setTimeout(function() {
        timeout = null;
        //calls another page to check if there's new data to display. if so, wipe existing data and update
        j$.ajax({
              url: "/include/new_Groups.php",
              cache: false,
              success: function(data){
                  j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
              },
              complete: function(data){
                  j$(document).trigger('mousemove');
              }
            })
              .done(function( html ) {
          });
    }, 3000);
});

您可以将计时器的想法转化为这种逻辑连接。。。

  1. 设置一个定时器3秒,之后你将进行AJAX调用

  2. 如果鼠标移动,则重置计时器3秒

现在,无论鼠标是否移动,您都有一个三秒的计时器在运行,并在鼠标移动时重置它,以获得您想要的仅在空闲时更新的行为。

var timeout = setTimeout(update, 3000);
function update() {
    clearTimeout(timeout);
    //calls another page to check if there's new data to display. if so, wipe existing data and update
    j$.ajax({
          url: "/include/new_Groups.php",
          cache: false,
          success: function(data){
              j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
          }
        }).done(function(html) {
        }).always(function() {
              timeout = setTimeout(update, 3000);
       });
}
j$(document).on('mousemove', function() {
    clearTimeout(timeout);
    timeout = setTimeout(update, 3000);
});

您应该使用setInterval()而不是setTimeout()来生成重复事件。

我会在事件处理程序代码之外调用setInterval(),然后让事件处理程序程序代码更新lastTimeMouseMoved(或其他)时间戳,该时间戳将由传递给setInterval()调用的代码进行检查。

所以,你的代码可能看起来像这样:

const IDLE_TIME = 3000;
var lastTimeMouseMoved = Date.now();
timer = setInterval(function() {
    if(Date.now() - lastTimeMouseMoved >= IDLE_TIME) {
        //calls another page to check if there's new data to display. if so, wipe existing data and update
        j$.ajax({
            url: "/include/new_Groups.php",
            cache: false,
            success: function(data){
                j$( ".group_Container_Main" ).append( data ).fadeIn('slow');
            }
        })
            .done(function( html ) { });
    } // end idle if
}, IDLE_TIME);
j$(document).on('mousemove', function() {
    lastTimeMouseMoved = Date.now();
});