检查页面是否在JavaScript中重新加载或刷新

当有人试图刷新页面时,我想检查一下。

例如,当我打开一个页面什么都没有发生,但当我刷新页面时,它应该显示一个警告。

489964 次浏览

我在这里找到了一些信息Javascript页面刷新检测。他的第一个建议是使用隐藏字段,这些字段往往是通过页面刷新存储的。

function checkRefresh() {
if (document.refreshForm.visited.value == "") {
// This is a fresh page load
document.refreshForm.visited.value = "1";
// You may want to add code here special for
// fresh page loads
} else {
// This is a page refresh
// Insert code here representing what to do on
// a refresh
}
}
<html>


<body onLoad="JavaScript:checkRefresh();">
<form name="refreshForm">
<input type="hidden" name="visited" value="" />
</form>


</body>


</html>

在有人第一次访问该页面时存储一个cookie。刷新时检查你的cookie是否存在,如果存在,提醒。

function checkFirstVisit() {
if(document.cookie.indexOf('mycookie')==-1) {
// cookie doesn't exist, create it now
document.cookie = 'mycookie=1';
}
else {
// not first visit, so alert
alert('You refreshed!');
}
}

在你的body标签中:

<body onload="checkFirstVisit()">

第一步是检查sessionStorage中的一些预定义值,如果存在,提醒用户:

if (sessionStorage.getItem("is_reloaded")) alert('Reloaded!');

第二步是将sessionStorage设置为某个值(例如true):

sessionStorage.setItem("is_reloaded", true);

会话值保持,直到页面关闭,所以它将工作,只有当页面重新加载在一个新的标签与网站。你也可以用同样的方法保持重载计数。

⚠️⚠️⚠️window.performance.navigation.type已弃用,请参阅Илья Зеленько的答案


了解页面是否实际被重新加载的更好方法是使用大多数现代浏览器支持的导航器对象。

它使用导航定时API

//check for Navigation Timing API support
if (window.performance) {
console.info("window.performance works fine on this browser");
}
console.info(performance.navigation.type);
if (performance.navigation.type == performance.navigation.TYPE_RELOAD) {
console.info( "This page is reloaded" );
} else {
console.info( "This page is not reloaded");
}

来源:https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API

我在这里发现了一些信息Javascript检测页面刷新

function UnLoadWindow() {
return 'We strongly recommends NOT closing this window yet.'
}


window.onbeforeunload = UnLoadWindow;

如果

event.currentTarget.performance.navigation.type

返回

0 =>用户刚刚输入了一个Url
1 => page reloaded

. 2 =>返回按钮单击

新标准2018-now (PerformanceNavigationTiming)

window.performance.navigation属性是导航授时等级2规范中的弃用。请使用PerformanceNavigationTiming接口。

PerformanceNavigationTiming.type . href="https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type" rel="noreferrer

这是一个实验技术

在生产中使用浏览器兼容性表之前,请仔细检查它。

检查页面是否在JavaScript中重新加载或刷新

const pageAccessedByReload = (
(window.performance.navigation && window.performance.navigation.type === 1) ||
window.performance
.getEntriesByType('navigation')
.map((nav) => nav.type)
.includes('reload')
);


alert(pageAccessedByReload);

2021-11-09支持

Table of support

type只读属性返回表示导航类型的字符串。必须为以下值之一:

  • 导航 -通过单击链接开始导航,在浏览器的地址栏中输入URL,提交表单,或通过脚本操作(而不是下面列出的重载和后退)初始化。

  • 重新加载 -导航是通过浏览器的重载操作或location.reload()

  • back_forward导航是通过浏览器的历史遍历操作。

  • prerender -导航由prerender提示启动。

此属性为只读。

下面的例子说明了这个属性的用法。

function print_nav_timing_data() {
// Use getEntriesByType() to just get the "navigation" events
var perfEntries = performance.getEntriesByType("navigation");


for (var i=0; i < perfEntries.length; i++) {
console.log("= Navigation entry[" + i + "]");
var p = perfEntries[i];
// dom Properties
console.log("DOM content loaded = " + (p.domContentLoadedEventEnd - p.domContentLoadedEventStart));
console.log("DOM complete = " + p.domComplete);
console.log("DOM interactive = " + p.interactive);
 

// document load and unload time
console.log("document load = " + (p.loadEventEnd - p.loadEventStart));
console.log("document unload = " + (p.unloadEventEnd - p.unloadEventStart));
    

// other properties
console.log("type = " + p.type);
console.log("redirectCount = " + p.redirectCount);
}
}

我写了这个函数来检查两个方法,同时使用旧的window.performance.navigation和新的performance.getEntriesByType("navigation"):

function navigationType(){


var result;
var p;


if (window.performance.navigation) {
result=window.performance.navigation;
if (result==255){result=4} // 4 is my invention!
}


if (window.performance.getEntriesByType("navigation")){
p=window.performance.getEntriesByType("navigation")[0].type;


if (p=='navigate'){result=0}
if (p=='reload'){result=1}
if (p=='back_forward'){result=2}
if (p=='prerender'){result=3} //3 is my invention!
}
return result;
}

结果描述:

0:点击一个链接,在浏览器的地址栏中输入URL,表单提交,点击书签,通过脚本操作初始化。

1:单击重新加载按钮或使用Location.reload()

2:使用浏览器历史记录(Bakc和Forward)。

3:预渲染活动,如<link rel="prerender" href="//example.com/next-page.html">

4:任何其他方法。

if(sessionStorage.reload) {
sessionStorage.reload = true;
// optionnal
setTimeout( () => { sessionStorage.setItem('reload', false) }, 2000);
} else {
sessionStorage.setItem('reload', false);
}




下面是一个几乎所有浏览器都支持的方法:

if (sessionStorage.getItem('reloaded') != null) {
console.log('page was reloaded');
} else {
console.log('page was not reloaded');
}


sessionStorage.setItem('reloaded', 'yes'); // could be anything

它使用SessionStorage来检查页面是否第一次被打开或是否被刷新。

<script>
    

var currpage    = window.location.href;
var lasturl     = sessionStorage.getItem("last_url");


if(lasturl == null || lasturl.length === 0 || currpage !== lasturl ){
sessionStorage.setItem("last_url", currpage);
alert("New page loaded");
}else{
alert("Refreshed Page");
}


</script>

在控制台添加以下脚本:

window.addEventListener("beforeunload", function(event) {
console.log("The page is redirecting")
debugger;
});
 document.addEventListener("keydown", (e)=>{
if (e.keyCode === 116) {
e.preventDefault();


// your code here
// var r = confirm("Reload!");
// if (r == true)
//  window.location.reload();
}
})
  1. 这里我们使用事件监听器“keydown”,因为F1 - F12键在浏览器上无法用于“keypress”。
  2. 116是“F5”的键码。检查在这里
  3. 'preventDefault()'将停止按下的键的默认功能。 在这里,当按下F5时,它会停止直接刷新
  4. 然后添加代码。
  5. 当警报被确认时,'location.reload()'将重新加载页面

一个简单的解决方案没有提到(不依赖于已弃用的window.performance.navigation):

  1. 使用window.onbeforeunload来存储用户离开页面(可能会刷新页面)时当前页面的时间和URL(在localstorage中)。
window.onbeforeunload = function(e)
{
localStorage.setItem('reload-url', window.location.href);
}
  1. 然后使用window.onload从本地存储中获取这些值。
window.onload = function(e)
{
if (localStorage.getItem('reload-url') != null))
{
if (window.location.href == localStorage.getItem('reload-url'))
{
console.log('Reload');
}
}
}
  1. 如果最近的URL与存储的URL匹配,如果存储的时间与当前时间匹配(可能有一个微小的偏移),那么它是用户重新加载的页面。

这个实现帮助了我:

MDN参考2022:导航授时级别2规范

const navigationType =
(window.performance.getEntriesByType('navigation')
[0] as PerformanceNavigationTiming).type;


const isPageReload = navigationType === 'reload';
const isNavigation = navigationType === 'navigate';
const isBackForwarad = navigationType === 'back_forward';
const isPrerender = navigationType === 'prerender';