提问人:mungnz 提问时间:10/19/2023 更新时间:10/19/2023 访问量:111
Chrome Leave Site popup & beforeunload 等
Chrome Leave Site popup & beforeunload et al
问:
我今天来上班,向一个公司网站的用户抱怨说,这些网站在导航到任何其他页面之前一直要求确认。我在更新 Chrome(我保持打开状态)之前和之后对其进行了测试,它从最新版本的 Chrome (118) 开始,适用于我和这个特定的网站。 此处的答案表明它是由 beforeunload 事件引起的,并禁用任何此类事件。我试过了,是的,这阻止了对话。
事情是这样的。当页面离开时,此站点将与服务器同步,并使用该事件来执行此操作。
...那么我该如何进行呢?
有没有另一种方式可以最后一次与服务器同步?我在执行之前卸载(等)错误吗?为什么它昨天工作,但今天不工作(我的意思是为什么 Chrome 修复了一些没有损坏的东西)?
我应该指出,我是自学成才的,虽然已经做了几年。我不像PHP那样喜欢JS方面,我在JS中所做的一切都感觉很糟糕,可能是错误的,但它使网站出来,因此可以使用它。
我曾尝试过使用 sendBeacon,但它从未真正起作用。也许我误解了它是如何工作的,也许它实际上不起作用,谁知道呢?因此,我使用了一个 post 方法,它只是 JQuery $.ajax 的包装器,但包含与特定站点相关的其他内容。
所以有一个通用的方法(它位于每个页面上加载的 app 对象中),它改编自过去的一些答案:
addUnloadEvent( unloadEvent ) {
let executed = false;
let exec = function ( event ) {
event.preventDefault();
if ( !executed ) {
executed = true;
return unloadEvent();
}
};
document.addEventListener( 'visibilitychange', function ( event ) {
if ( document.visibilityState === 'hidden' ) {
exec( event );
}
}, { capture : true } );
window.addEventListener( "pagehide", exec, { capture : true } );
window.addEventListener( "beforeunload", exec, { capture : true } );
window.onbeforeunload = exec;
window.addEventListener( 'unload', exec, { capture : true } );
},
可能看起来像是一种霰弹枪方法,丑陋,糟糕,但你知道,我只需要让这个愚蠢的东西工作,这样客户就可以使用该网站。
不同的控制器有自己的 js 文件,用于扩展 app 方法,并且可以运行 init 方法,在一个特定控制器的特定 init 函数中,我们有这个:
....
$app.addUnloadEvent( function () {
return $app.syncBasketWithServer();
} );
....
该方法是:
syncBasketWithServer() {
return $app.post( '/order/syncBasket', { 'Basket' : $app.Basket }, function ( data ) {
return data.status === 'success';
} );
}
答:
因此,如果满足某些条件,则该事件将阻止用户离开:beforeunload
- 调用事件对象的 preventDefault() 方法。
- 将事件对象的 returnValue 属性设置为非空字符串值或任何其他真实值。
- 从事件处理程序函数返回任何真实值
请参见:https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
由于您在事件处理程序中做的第一件事是调用 preventDefault(),因此将触发该消息。
无论如何,当用户离开什么时提出请求(我会说)是不好的做法。 最好在找零时同步购物篮,而不是在休假时同步。 如果您需要这些信息,您可以发送请求,但据我所知,不能保证会发送请求。
如果您确实需要用户离开的信号,也许可以打开与用户的连接(Websocket,打开HTTP连接),如果用户断开连接,它将触发信标。
评论