【问题标题】:Display a warning after 3 mins of inactivity on a page在页面上闲置 3 分钟后显示警告
【发布时间】:2013-04-15 14:11:19
【问题描述】:

我正在开发一个带有测试的 php 页面。测试的最长时间为 1 小时,但会话在 10 分钟不活动后超时。超时时,测试页面不会刷新或重定向......它保持不变,但是当用户在测试结束时点击“查看结果”按钮时,他会退出并且他的结果不会被注册。

我只需要 - [在页面上闲置 3 分钟后] - 显示警告消息。 如果在显示消息后用户在页面上的任意位置移动鼠标或单击,则计时器会重置而不刷新页面。

如果即使在显示警告消息后,用户在 7 分钟内没有移动鼠标或单击,则消息显示“您已注销”。

我是编程的初学者,但我想这很简单,在 3 分钟和 10 分钟不活动后显示 2 条消息,在鼠标移动或单击时都会重置计时器。

有人可以帮我解决这个问题吗?谢谢!

【问题讨论】:

  • window.setTimeout(function() { alert('3 minute warning') }, 30000); 检测活动留给读者作为练习。
  • @Marc B 这不是 3 分钟不活动
  • 虽然它可能已经关闭,但是将这个计时器附加到一个监听键盘按下和鼠标移动的事件上,它可能会完成这项工作。
  • 仅供参考。 HTTP 中的活动表示服务器请求

标签: javascript jquery ajax


【解决方案1】:
var timeoutWarn;
var timeoutLogout;

// Set the timer
resetTimer();

// Reset the timer
document.onmousemove = resetTimer();
document.onclick = resetTimer();

function resetTimer = function() {
    timeoutWarn = window.setTimeout(function() { 
        // create warning element.
    }, 180000);

    timeoutLogout = window.setTimeout(function() { 
        // ajax to process logout
        alert('You have been logged out');
    }, 420000);
}

【讨论】:

  • 好,然后执行一个检查移动鼠标/点击?
【解决方案2】:

如果您真的想保持正确,请假设任何客户端都是可伪造的,而忘记 JS 解决方案。唯一正确的方法是服务器端。但是,不幸的是,HTTP 请求是无状态的,这意味着您不确切知道客户端在做什么以及他是否仍然处于活动状态。您可以做的是在每个请求上更新会话信息服务器端,并且每分钟一次,您有一个 cron 作业作为过期会话的垃圾收集器。

【讨论】:

    【解决方案3】:
    var timeout;
    
    document.onmousemove = resetTimer;
    document.onclick = resetTimer;
    
    function resetTimer = function() {
      clearTimeout(timeout);
      timeout = setTimeout(function(){alert("3 minute warning");}, 3*60*1000);
    }
    

    正如@Elzo Valugi 所说,您的服务器将无法验证您在客户端所做的任何事情,因此如果这很重要,您还需要添加服务器端代码。

    【讨论】:

      【解决方案4】:

      这应该允许您在不修改核心计时器逻辑的情况下调整区域和实际毫秒/操作

      var $area = $(document),
          idleActions = [
              {
                  milliseconds: 3000, // 3 seconds
                  action: function () { alert('Warning'); }
              },
              {
                  milliseconds: 3000, // 3 + 3 = 6 seconds
                  action: function () { alert('Logout'); }
              }
          ];
      
      
      function Eureka (event, times, undefined) {
          var idleTimer = $area.data('idleTimer');
          if (times === undefined) times = 0;
          if (idleTimer) {
              clearTimeout($area.data('idleTimer'));
          }
          if (times < idleActions.length) {
              $area.data('idleTimer', setTimeout(function () {
                  idleActions[times].action(); // run the first action
                  Eureka(null, ++times); // setup the next action
              }, idleActions[times].milliseconds));
          } else {
              // final action reached, prevent further resetting
              $area.off('mousemove click', Eureka);
          }
      };
      
      $area
          .data('idle', null)
          .on('mousemove click', Eureka);
      
      Eureka(); // start the first time
      

      jsFiddle:http://jsfiddle.net/terryyounghk/wMZJA/

      【讨论】:

      • 谢谢,特里!这似乎以某种方式起作用,但即使我移动鼠标或滚动它也会触发。如果我在“警告”之后移动鼠标,则会触发“注销”,只有当我在“警告”之后不移动鼠标时才会触发。如果警告后我重新开始活动然后再次停止,它应该再次触发“警告”。
      • 虽然我对此进行了更多思考,但这种情况是否也发生在我的演示链接中(我似乎无法重现)?您是否有可能在文档中有某些元素阻止事件传播,从而阻止事件到达document(因此$area)?如果是这种情况,请调整 $area 的选择器,我有点预料到。
      • 例如:var $area = $([document, 'body', '.SomeElementThatPreventedEventPropagation'])
      • 我认为scroll 事件不会触发mousemove 事件。无论您想添加什么事件,只有两个地方可以修改(或者如果您愿意,可以将其抽象为一个变量)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多