如何在一段时间不活动后自动重新加载页面

170

如果在给定的时间段内页面没有任何活动,我该如何自动重新加载网页?


也许这个问题与https://dev59.com/tVDTa4cB1Zd3GeqPJ4ZA有关? - Raghuram
17个回答

252

这可以在不使用 JavaScript 的情况下通过以下元标记实现:

<meta http-equiv="refresh" content="5" >

在content="5"中的"5"代表页面等待刷新的秒数。

但是你说只有在没有任何活动时才会刷新,这里所说的活动指的是什么?


4
"没有活动"意味着最终用户不在桌面前或正在浏览其他网站。我参考的网站上没有鼠标/键盘活动。 - Umar Adil
2
很棒的答案,我以为必须使用setInterval来完成,现在很高兴知道这个存在! - tim peterson
17
虽然这并不是答案,因为它没有涵盖活动,但它是谷歌搜索结果中最顶部的问题,当你只是简单地寻找用JavaScript刷新页面的方法时,这是可行的选择。请点赞这个回答。如果你想让页面在一定时间间隔内自动刷新,就使用这个方法。 - Jimmy Bosse
我们能否使用POST变量进行自动刷新? - Pradeep Kumar
3
这并不回答问题。如果有活动,它将重新加载。 - Braian Mellor
显示剩余4条评论

245

如果您希望在没有活动的情况下刷新页面,那么您需要找出如何定义活动。假设我们每分钟刷新页面,除非有人按键或移动鼠标。这里使用jQuery进行事件绑定:

<script>
     var time = new Date().getTime();
     $(document.body).bind("mousemove keypress", function(e) {
         time = new Date().getTime();
     });

     function refresh() {
         if(new Date().getTime() - time >= 60000) 
             window.location.reload(true);
         else 
             setTimeout(refresh, 10000);
     }

     setTimeout(refresh, 10000);
</script>

5
如果计算使用的是60000,为什么要将间隔设置为10000?这样至少在5次轮回中会出错吗? - Scary Wombat
4
间隔时间比不活动时间短的原因在于,您希望以比实际不活动时间更高的频率检查不活动时间。例如,如果不活动时间为1分钟,间隔时间为1分钟,则如果用户在1秒后移动鼠标然后停止,刷新将在2分钟后才发生。间隔时间越短,刷新时间就越准确。 - Derorrist

61
我已经构建了一个完整的JavaScript解决方案,不需要jQuery。可能可以将其转化为插件。我用它来实现流体自动刷新,但是看起来它也可以帮助你。 JSFiddle AutoRefresh
// Refresh Rate is how often you want to refresh the page 
// bassed off the user inactivity. 
var refresh_rate = 200; //<-- In seconds, change to your needs
var last_user_action = 0;
var has_focus = false;
var lost_focus_count = 0;
// If the user loses focus on the browser to many times 
// we want to refresh anyway even if they are typing. 
// This is so we don't get the browser locked into 
// a state where the refresh never happens.    
var focus_margin = 10; 

// Reset the Timer on users last action
function reset() {
    last_user_action = 0;
    console.log("Reset");
}

function windowHasFocus() {
    has_focus = true;
}

function windowLostFocus() {
    has_focus = false;
    lost_focus_count++;
    console.log(lost_focus_count + " <~ Lost Focus");
}

// Count Down that executes ever second
setInterval(function () {
    last_user_action++;
    refreshCheck();
}, 1000);

// The code that checks if the window needs to reload
function refreshCheck() {
    var focus = window.onfocus;
    if ((last_user_action >= refresh_rate && !has_focus && document.readyState == "complete") || lost_focus_count > focus_margin) {
        window.location.reload(); // If this is called no reset is needed
        reset(); // We want to reset just to make sure the location reload is not called.
    }

}
window.addEventListener("focus", windowHasFocus, false);
window.addEventListener("blur", windowLostFocus, false);
window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);

4
太棒了!希望你在这里能获得更多的赞。不使用jQuery将获得重要的加分。 - Echiban
1
  • 非常感谢 / 多谢
  • 这是否考虑了检测触摸事件?
- DotDotJames
1
嗯,你知道我不太确定。当我创建它时,我没有很多 iPhone 或 iPad 的经验。 - User128848244
1
英雄!太完美了,谢谢。我已将我的PHP会话设置为在一小时后过期,并且这是在一小时多一点时刷新的。我认为这应该实现了我想要的不活动后注销功能。 - Tspesh
请问如果我想暂停计时器而不是重置,您能提供一个解决方案吗? - karjaubayev
谢谢,为什么代码在reload()后调用reset()呢? 它会被执行吗? - Itamar K.

23
<script type="text/javascript">
  var timeout = setTimeout("location.reload(true);",600000);
  function resetTimeout() {
    clearTimeout(timeout);
    timeout = setTimeout("location.reload(true);",600000);
  }
</script>

以上代码将每隔10分钟刷新页面,除非调用resetTimeout()函数。例如:

<a href="javascript:;" onclick="resetTimeout();">clicky</a>

3
隐式求值是彻头彻尾的恶! - Stephan Weinhold

9
基于arturnt所提供的答案,这是一个稍微优化过的版本,但本质上做的事情是一样的。
var time = new Date().getTime();
$(document.body).bind("mousemove keypress", function () {
    time = new Date().getTime();
});

setInterval(function() {
    if (new Date().getTime() - time >= 60000) {
        window.location.reload(true);
    }
}, 1000);

唯一的区别是该版本使用setInterval而不是setTimeout,这使得代码更加简洁。


如果它使用的计算值为 60000,为什么要将间隔设置为 1000? - Scary Wombat
3
间隔是1.000,因为它每秒检查一次鼠标是否移动。然后使用60.000来确定上次鼠标移动是否至少在一分钟之前发生。 - Hannes Sachsenhofer

6
var bd = document.getElementsByTagName('body')[0];
var time = new Date().getTime();

bd.onmousemove = goLoad;
function goLoad() {
    if(new Date().getTime() - time >= 1200000) {
        time = new Date().getTime();
        window.location.reload(true);
    }else{
        time = new Date().getTime();
    }
}

每次移动鼠标时,它会检查上一次你移动鼠标的时间。如果时间间隔大于20秒,它将重新加载页面,否则它将更新上一次移动鼠标的时间。

4

使用JavaScript的setInterval方法:

setInterval(function(){ location.reload(); }, 3000);

2

自动重新加载页面,可以选择目标。在本例中,目标是_self设置为自身,但您可以通过简单地更改window.open('self.location', '_self');代码来更改重新加载页面,例如:window.top.location="window.open('http://www.YourPageAdress.com', '_self'";

带确认提示信息:

<script language="JavaScript">
function set_interval() {
  //the interval 'timer' is set as soon as the page loads  
  var timeoutMins = 1000 * 1 * 15; // 15 seconds
  var timeout1Mins = 1000 * 1 * 13; // 13 seconds
  itimer=setInterval("auto_logout()",timeoutMins);
  atimer=setInterval("alert_idle()",timeout1Mins);

}

function reset_interval() {
  var timeoutMins = 1000 * 1 * 15; // 15 seconds 
  var timeout1Mins = 1000 * 1 * 13; // 13 seconds
  //resets the timer. The timer is reset on each of the below events:
  // 1. mousemove   2. mouseclick   3. key press 4. scrolling
  //first step: clear the existing timer
  clearInterval(itimer);
  clearInterval(atimer);
  //second step: implement the timer again
  itimer=setInterval("auto_logout()",timeoutMins);
  atimer=setInterval("alert_idle()",timeout1Mins);
}

function alert_idle() {
    var answer = confirm("Session About To Timeout\n\n       You will be automatically logged out.\n       Confirm to remain logged in.")
    if (answer){

        reset_interval();
    }
    else{
        auto_logout();
    }
}

function auto_logout() {
  //this function will redirect the user to the logout script
  window.open('self.location', '_self');
}
</script>

没有确认提示:

<script language="JavaScript">
function set_interval() {
  //the interval 'timer' is set as soon as the page loads  
  var timeoutMins = 1000 * 1 * 15; // 15 seconds
  var timeout1Mins = 1000 * 1 * 13; // 13 seconds
  itimer=setInterval("auto_logout()",timeoutMins);

}

function reset_interval() {
  var timeoutMins = 1000 * 1 * 15; // 15 seconds 
  var timeout1Mins = 1000 * 1 * 13; // 13 seconds
  //resets the timer. The timer is reset on each of the below events:
  // 1. mousemove   2. mouseclick   3. key press 4. scrolling
  //first step: clear the existing timer
  clearInterval(itimer);
  clearInterval(atimer);
  //second step: implement the timer again
  itimer=setInterval("auto_logout()",timeoutMins);
}


function auto_logout() {
  //this function will redirect the user to the logout script
  window.open('self.location', '_self');
}
</script>

正文代码对两种解决方案都相同:

<body onLoad="set_interval(); document.form1.exp_dat.focus();" onKeyPress="reset_interval();" onmousemove="reset_interval();" onclick="reset_interval();" onscroll="reset_interval();">

如果有活动,无论如何它都会重新加载。 - Braian Mellor
1
你说得对,我没有完整地阅读问题。现在已经编辑过了,附上了正确的答案。 - SeekLoad
我去掉了-1并加上了+10以得到更好的答案!谢谢 - Braian Mellor
我还有第二个可行的答案,但现在我正在微调这个答案,因为它可以通过有针对性的解决方案变得更好,就像我现在所编辑的那样。 - SeekLoad
1
我现在给出了3个解决方案的答案,具体取决于哪个更容易应用或符合需求。这3个解决方案都可以使用确认或警告,也可以不使用。我回答了3个答案,因为这3个答案是由不同的代码组成的,将它们全部放在一个答案中会太长。此外,我还添加了如何编辑代码的说明。当然,所有的答案都完美地工作...在我把它们放在这里之前已经进行了测试。 - SeekLoad

1

我提出了一个稍微不同的解决方案,因为我发现setInterval并不是非常准确,参见:setInterval timing slowly drifts away from staying accurate

// Based on https://dev59.com/KW445IYBdhLWcg3w5OMI#15279599

// Refresh Rate is how often you want to refresh the page
// based off the user inactivity (in seconds).
var refresh_after = 20;
var last_user_action = new Date();

// Reset the Timer on users last action
function reset() {
    last_user_action = new Date();
}

// Countdown that executes every second.
setInterval(function () {
    refreshCheck();
}, 1000);

// The code that checks if the window needs to reload
function refreshCheck() {
    var expire_time = new Date(last_user_action);
    expire_time.setSeconds(expire_time.getSeconds() + refresh_after);
    now = new Date();
    if (now.getTime() >= expire_time.getTime() && document.readyState == "complete") {
        window.location.href = window.location.href; // We do this to discard the POST data.
    }
}

window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);

0

使用页面确认文本而非警告框

由于这是另一种在不活动时自动加载的方法,我提供了第二个答案。这个更简单易懂。

使用页面重新加载确认

<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5100; // 5,1 seconds
var warnPeriod = 5000; // 5 seconds
// Warning period should always be a bit shorter then time period

function promptForClose() {
autoCloseDiv.style.display = 'block';
autoCloseTimer = setTimeout("definitelyClose()", warnPeriod);
}


function autoClose() {
autoCloseDiv.style.display = 'block'; //shows message on page
autoCloseTimer = setTimeout("definitelyClose()", timePeriod); //starts countdown to closure
}

function cancelClose() {
clearTimeout(autoCloseTimer); //stops auto-close timer
autoCloseDiv.style.display = 'none'; //hides message
}

function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("promptForClose()", timePeriod); //restarts timer from 0
}


function definitelyClose() {

// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or  this: window.open('http://www.YourPageAdress.com', '_self');

// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');

window.top.location=self.location;
}
-->
</script>

在页面确认时使用确认框

<div class="leftcolNon">
<div id='autoCloseDiv' style="display:none">
<center>
<b>Inactivity warning!</b><br />
This page will Reloads automatically unless you hit 'Cancel.'</p>
<input type='button' value='Load' onclick='definitelyClose();' />
<input type='button' value='Cancel' onclick='cancelClose();' />
</center>
</div>
</div>

两者的主体代码是相同的

<body onmousedown="resetTimeout();" onmouseup="resetTimeout();" onmousemove="resetTimeout();" onkeydown="resetTimeout();" onload="timeoutObject=setTimeout('promptForClose()',timePeriod);">

注意:如果您不想要页面上的确认,请使用无需确认

<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5000; // 5 seconds

function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("definitelyClose()", timePeriod); //restarts timer from 0
}

function definitelyClose() {

// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or  this: window.open('http://www.YourPageAdress.com', '_self');

// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');

window.top.location=self.location;
}
-->
</script>

我现在为同一个解决方案提供了3个答案,具体取决于哪个更容易应用或符合需求。这3个解决方案都可以有或没有确认或警报。我回答了3个答案,因为这3个答案具有不同的代码,将所有解决方案放在一个答案中会太长。此外,我还添加了如何编辑代码的说明。当然,所有答案都完美地工作...在我发布它们之前已经进行了测试。 - SeekLoad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接