如何在 JavaScript 事件中区分页面关闭和页面刷新?
在 Web 开发中,有时你需要监听页面关闭或刷新事件,并根据情况执行不同的操作。可以监听页面关闭或刷新事件,但无法区分这两者。通过设置一个标记,可以判断页面是否刷新。通过检查,可以确定页面是否被刷新。虽然事件能处理很多场景,但如果你需要更精确的控制,可以结合或来判断页面是否刷新。记住需要进行适当的兼容性测试。
如何在 JavaScript 事件中区分页面关闭和页面刷新?
往期文章:
在开发 Web 应用时,有时你可能需要监听用户关闭页面或刷新页面的行为。
例如,用户关闭当前页面清空token,而刷新时候不做处理。
例如,你可能想在用户离开页面时保存未保存的数据,或者在页面刷新时执行一些特定的操作。
如何区分这两种行为(关闭页面和刷新页面)却不是那么直观。
我们需要使用一些特定的 API,巧妙地实现这一功能。
在本文中,我们将使用 beforeunload 事件来监听浏览器页面的关闭与刷新行为,并通过几种不同的方法来区分它们。
使用 beforeunload 事件监听页面关闭和刷新
beforeunload 事件是浏览器在用户关闭页面、刷新页面或跳转到另一个页面时触发的事件。你可以通过这个事件来做一些清理工作,或者提示用户保存未保存的内容。最常见的应用场景是在页面关闭或刷新时弹出确认框。
监听 beforeunload 事件
window.addEventListener('beforeunload', function (event) {
// 自定义提示消息
const message = 'Are you sure you want to leave?';
event.returnValue = message; // 对老版本浏览器的支持
return message; // 对现代浏览器的支持
});
说明:
- 当用户试图离开当前页面时(包括刷新或关闭页面),浏览器会显示一个确认框,询问用户是否确定离开。
event.returnValue或者直接return提示消息都会触发浏览器的默认行为,弹出提示框。
注意:
- 现代浏览器对这个事件的支持有所限制,特别是在弹出框的内容上。为了防止恶意行为,浏览器可能只显示默认的提示文本。
beforeunload事件会在页面刷新和关闭时都被触发,因此无法直接区分这两者。
如何区分页面刷新与页面关闭
虽然 beforeunload 事件能够监听页面的关闭与刷新,但它不能直接告诉你是页面被刷新还是被关闭。为了实现这一点,我们需要使用一些额外的技巧。以下是几种方法:
方法 1:使用 sessionStorage 来区分刷新和关闭
如何利用 sessionStorage 判断页面是否是刷新?
- 初次加载:当页面第一次加载时,
sessionStorage是空的。 - 刷新页面:当页面被刷新时,
sessionStorage会保留在当前会话中,但它的内容不会被清空,直到页面被关闭。 - 关闭页面:当页面关闭时,
sessionStorage会被清空。
因此,我们可以通过在页面加载时设置一个标识符来检测是否是页面刷新。
实现代码:
// 页面加载时执行
window.onload = function() {
// 检查 sessionStorage 中是否有标记
if (sessionStorage.getItem('refreshed') === 'true') {
console.log('页面被刷新');
sessionStorage.removeItem('refreshed'); // 清除标记
} else {
console.log('页面被加载');
}
};
// 监听 beforeunload 事件
window.addEventListener('beforeunload', function(event) {
// 设置 sessionStorage 标记
sessionStorage.setItem('refreshed', 'true');
});
// 监听 unload 事件
window.addEventListener('unload', function(event) {
// 页面关闭时执行的操作
console.log('页面被关闭');
});
解释:
- 当页面加载时
onload,我们判断sessionStorage中的refreshed标记设置为true,表示页面已经刷新过。 - 当
beforeunload事件触发时,我们设置sessionStorage中的标记为true。 - 刷新时候,
sessionStorage中的值一直存在,关闭后sessionStorage值被清除。
方法 2:使用 localStorage 来区分刷新和关闭
https://segmentfault.com/a/1190000019305127)
在浏览器关闭前是无法判断用户是刷新还是退出,所以我们在用户再次打开的时候来判断用户是否刷新
解决思路:
- 用户关闭浏览器时,记录当前时间,并存于浏览器缓存中
- 用户再次打开页面时,获取上次退出的时间,并于当前时间进行比较,若小于5s则表示用户执行的是刷新操作,若大于5s则判定为退出
注意: 5s并非固定,要根据实际情况调整,(根据网速,一般刷新页面时间在五秒内,用户关闭再打开页面时间大于5s)
实现代码:
// 记录当前时间并转成时间戳
const currentTime = new Date().getTime();
// 从缓存中获取用户上次退出的时间戳
const lastTime = parseInt(localStorage.getItem('leaveTime'));
console.log(currentTime, lastTime, currentTime - lastTime, 'leaveTime');
// 判断是否为刷新,两次间隔在5s内判定为刷新操作
const isFreshed = currentTime - lastTime <= 5000;
// 测试alert
console.log(isFreshed ? '刷新' : '重新登陆');
window.addEventListener('beforeunload', (e)=>{
let currentTime = new Date().getTime();
localStorage.setItem('leaveTime', currentTime);
});
方法 3:使用 performance.navigation 判断页面刷新
浏览器的 performance.navigation 接口可以帮助我们判断页面是通过刷新加载的,还是通过点击链接或其他方式加载的。
实现代码:
window.addEventListener('beforeunload', function (event) {
if (window.performance && window.performance.navigation.type === window.performance.navigation.TYPE_RELOAD) {
// 页面被刷新
console.log('The page is being refreshed.');
} else {
// 页面正在关闭
console.log('The page is being closed.');
}
});
解释:
-
performance.navigation.type返回一个数字,表示页面的加载类型:
0(TYPE_NAVIGATE):正常的页面加载(例如通过链接跳转)。1(TYPE_RELOAD):页面刷新。2(TYPE_BACK_FORWARD):通过浏览器的前进或后退按钮加载页面。
-
通过检查这个值,我们可以判断当前页面是刷新还是关闭。
注意:
performance.navigation在某些浏览器中可能不被完全支持,特别是在移动端设备上,建议在使用前进行兼容性测试。
方法4:使用 window.event.screenY 判断页面刷新(IE支持)
window.onbeforeunload = (e) => {
if ((event.clientX > document.body.clientWidth && event.clientY < 0) || event.altKey) {
alert('你关闭了浏览器')
} else {
alert('你正在刷新页面')
}
// e.returnValue = '确认关闭'
return '确认关闭'
}
总结
在 Web 开发中,有时你需要监听页面关闭或刷新事件,并根据情况执行不同的操作。通过以下几种方法,你可以实现对页面关闭和页面刷新的区分:
beforeunload事件: 可以监听页面关闭或刷新事件,但无法区分这两者。localStorage: 通过设置时间戳标记,可以判断页面是否刷新。sessionStorage: 通过sessionStorage特有特性实现效果performance.navigation: 通过检查performance.navigation.type,可以确定页面是否被刷新。
虽然 beforeunload 事件能处理很多场景,但如果你需要更精确的控制,可以结合 sessionStorage 或 performance.navigation 来判断页面是否刷新。
记住,performance.navigation需要进行适当的兼容性测试。
更多推荐


所有评论(0)