【问题标题】:Javascript timer doesn't run if page not active page viewed如果页面未查看活动页面,则 Javascript 计时器不会运行
【发布时间】:2012-05-19 19:34:09
【问题描述】:

我知道这个问题听起来很奇怪,但问题就在这里,以下代码完美运行。计时器从 30 分钟开始,每秒钟未检测到鼠标移动都会倒计时。当检测到鼠标移动时,计时器重置为 30 分钟,在页面不活动的 25 分钟标记处,一个 CSS 弹出窗口显示倒计时最后 5 分钟,在 30 分钟时,用户自动注销。但是,如果用户打开了页面但正在完全查看另一个网页,则计时器会减慢或完全停止,具体取决于浏览器。这实际上完全否定了脚本。是否可以让脚本继续正常倒计时,并且即使用户没有主动查看页面,仍然强制用户离开页面?或者这些浏览器怪癖是为了减少内存负载?

     var Timing = 0;
     var CounterTime = 0;
     var TimePast = 0;
     var Seconds = 1800;
     var Warn = 1500;
     var MinuteLeft = 30;
     var SecondLeft = 60;
     var StopRefresh = 0;

     function ResponseTime()
     {
          Timing = Timing + 100;
          CounterTime = CounterTime + 100;
          if(Timing % 1000 == 0)
          {
                TimePast = TimePast + 1;
                SecondLeft = SecondLeft - 1;
                if(SecondLeft == 59)
                {
                     MinuteLeft = MinuteLeft-1; 
                }
                if(SecondLeft == 0)
                {
                     SecondLeft = 60;
                }
          }
          if(MinuteLeft != 0)
          {
                if(SecondLeft == 60)
                {
                      document.getElementById('CountdownTimer').firstChild.nodeValue = MinuteLeft+":00";
                }else if(SecondLeft < 10)
                {
                      document.getElementById('CountdownTimer').firstChild.nodeValue = MinuteLeft+":0"+SecondLeft;
                }else
                {
                      document.getElementById('CountdownTimer').firstChild.nodeValue = MinuteLeft+":"+SecondLeft;
                }
                if((MinuteLeft == 0) && (SecondLeft <= 10))
                {
                      document.getElementById('CountdownTimer').style.fontWeight = "bolder";
                      document.getElementById('CountdownTimer').style.color = "red";
                }
                      document.getElementById('CountdownTimer').style.fontWeight = "normal";
                      document.getElementById('CountdownTimer').style.color = "black";
                }else
                {
                      document.getElementById('CountdownTimer').firstChild.nodeValue = SecondLeft;
                if((MinuteLeft == 0) && (SecondLeft <= 10))
                {
                      document.getElementById('CountdownTimer').style.fontWeight = "bolder";
                      document.getElementById('CountdownTimer').style.color = "red";
                }else
                {
                      document.getElementById('CountdownTimer').style.fontWeight = "normal";
                      document.getElementById('CountdownTimer').style.color = "black";          
                }
          }
          if(TimePast == 1800)
          {
                 document.getElementById('DoLogoutRequest').submit();   
          }
          if(MinuteLeft <=4)
          {
                 document.getElementById('Overlay').style.visibility="visible";
                 document.getElementById('ForceLogout').style.visibility="visible";
          }else
          {
                 document.getElementById('Overlay').style.visibility="hidden";
                 document.getElementById('ForceLogout').style.visibility="hidden";  
          }
          $(document).ready(function(){
                 $(document).mousemove(function(){
                        Timing = 0;
                        TimePast = 0;
                        SecondLeft = 60;
                        MinuteLeft = 29;
                 });
           });
      }

【问题讨论】:

  • 我没有看到任何 setInterval 或 setTimeout 调用。你是如何运行计时器的?

标签: javascript javascript-events


【解决方案1】:

您可以做的是修改脚本,以便在检测到 mousemove 时,首先检查自上次 mousemove 事件以来的当前秒数(使用 Date 对象)。

如果超过 30 分钟,那么您知道该个人应该退出,然后您可以立即采取该操作。

可以将其想象为设置了一条在 30 秒标记处武装但在有人绊倒它之前不会触发的绊线。

不过,话虽如此,我确实非常担心这种方法的安全性。一般来说,客户端代码是不安全的。诸如自动注销用户之类的事情实际上应该在服务器端使用会话来处理。

不过,这种方法很有创意,因为它不会强迫我访问不同的页面。因此,您可以使用的另一种将服务器端方法与 mouseevent 方法相结合的技术是将鼠标移动和时间存储在一个变量中。然后,在您的 29:30 分钟标记处,如果数组包含在过去 25 分钟内发生的鼠标移动,则向服务器发出安全 AJAX 请求以告知会话用户仍处于活动状态。

这将减少服务器上的负载,因为您只在需要时进行更新,并且它还允许您的用户使用应用程序而无需刷新以防止注销,并且它还将保留实际的 "用户是否登录”是它所属的逻辑的一部分,在服务器上。如果服务器从未收到客户端的响应,则服务器会将用户注销。

总而言之,您的服务器不会永远等待以听到可以注销用户:

      if(TimePast == 1800)
      {
             document.getElementById('DoLogoutRequest').submit();   
      }

如果服务器没有听到您的客户签入,则服务器会采取更权威的方法在没有您的情况下继续前进:

      if(TimePast <= 1800 && TimePast >= 1700)
      {
             // send keepalive request to the server to prevent auto-logout

      }

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    相关资源
    最近更新 更多