区分不同类型的 beforeunload 事件
Posted
技术标签:
【中文标题】区分不同类型的 beforeunload 事件【英文标题】:Distinguish between different types of beforeunload events 【发布时间】:2021-12-10 20:47:31 【问题描述】:在 javascript 中,是否可以区分由用户关闭浏览器选项卡和单击 mailto
链接触发的 beforeunload
事件?
基本上,我想这样做:
window.addEventListener("beforeunload", function (e)
if(browserTabClosed)
// Do one thing
else if (mailtoLinkClicked)
// Do a different thing
【问题讨论】:
了解您的应用程序为何需要区分您描述的情况可能很有用? 【参考方案1】:通过查看传入的事件(下面的e
)找到了解决方案:
window.addEventListener("beforeunload", function (e)
// We can use `e.target.activeElement.nodeName`
// to check what triggered the passed-in event.
// - If triggered by closing a browser tab: The value is "BODY"
// - If triggered by clicking a link: The value is "A"
const isLinkClicked = (e.target.activeElement.nodeName === "A");
// If triggered by clicking a link
if (isLinkClicked)
// Do one thing
// If triggered by closing the browser tab
else
// Do a different thing
【讨论】:
【参考方案2】:beforeunload
方法在浏览器之间的行为不稳定,原因是浏览器实现试图避免弹出窗口和其他在此处理程序中运行的恶意代码。
实际上没有通用(跨浏览器)方法来检测触发beforeunload
事件的原因。
说,在您的情况下,您可以检测到点击 window
以区分两种必需的行为:
window.__exit_with_link = false;
window.addEventListener('click', function (e)
// user clicked a link
var isLink = e.target.tagName.toLowerCase() === 'a';
// check if the link has this page as target:
// if is targeting a popup/iframe/blank page
// the beforeunload on this page
// would not be triggered anyway
var isSelf = !a.target.target || a.target.target.toLowerCase() === '_self';
if (isLink && isSelf)
window.__exit_with_link = true;
// ensure reset after a little time
setTimeout(function() window.__exit_with_link = false; , 50);
else window.__exit_with_link = false;
);
window.addEventListener('beforeunload', function (e)
if (window.__exit_with_link)
// the user exited the page by clicking a link
else
// the user exited the page for any other reason
显然这不是正确的方法,但仍然有效。
同样,您可以添加其他处理程序来检查用户离开页面的其他原因(例如,键盘 CTRL-R 用于刷新等)
【讨论】:
以上是关于区分不同类型的 beforeunload 事件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 beforeunload 事件上设置我自己的消息 [重复]