我想捕获浏览器窗口/选项卡关闭事件.我用jQuery尝试了以下内容:
jQuery(window).bind(
"beforeunload",
function() {
return confirm("Do you really want to close?")
}
)
Run Code Online (Sandbox Code Playgroud)
但它也适用于表单提交,这不是我想要的.我想要一个仅在用户关闭窗口时触发的事件.
无法处理此断开事件,不知道为什么socket不发送给客户端/客户端没有响应!
服务器
io.sockets.on('connection', function (socket) {
socket.on('NewPlayer', function(data1) {
online = online + 1;
console.log('Online players : ' + online);
console.log('New player connected : ' + data1);
Players[data1] = data1;
console.log(Players);
});
socket.on('DelPlayer', function(data) {
delete Players[data];
console.log(Players);
console.log('Adios' + data);
});
socket.on('disconnect', function () {
socket.emit('disconnected');
online = online - 1;
});
});
Run Code Online (Sandbox Code Playgroud)
客户
var socket = io.connect('http://localhost');
socket.on('connect', function () {
person_name = prompt("Welcome. Please enter your name");
socket.emit('NewPlayer', person_name);
socket.on('disconnected', function() {
socket.emit('DelPlayer', person_name);
});
});
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,当客户端断开连接时,应该删除数组对象[person_name],但不是
有没有人知道我可以使用javascript检查浏览器窗口何时关闭并弹出确认dailog以询问用户是否确认退出浏览器或更改他的想法留下?
我有一个对象列表。用户可以单击其中一个,然后加载一个子组件来编辑该组件。
我遇到的问题是,当用户返回列表组件时,子组件必须在 ngOnDestroy 方法中进行一些清理 - 这需要调用服务器来对对象进行最终的“修补”。有时此处理可能会有点慢。
当然,发生的情况是用户返回列表,并且该 api 调用在数据库事务完成之前完成ngOnDestroy,因此用户看到的是过时的数据。
ngOnDestroy(){
this.destroy$.next();
this.template.template_items.forEach((item, index) => {
// mark uncompleted items for deletion
if (!item.is_completed) {
this.template.template_items[index]['_destroy'] = true;
};
});
// NOTE
// We don't care about result, this is a 'silent' save to remove empty items,
// but also to ensure the final sorted order is saved to the server
this._templateService.patchTemplate(this.template).subscribe();
this._templateService.selectedTemplate = null;
}
Run Code Online (Sandbox Code Playgroud)
我知道不建议进行同步调用,因为它会阻塞 UI/整个浏览器,这不太好。
我确信有多种方法可以解决这个问题,但真的不知道哪种方法最好(特别是因为 Angular 不支持同步请求,所以我必须回退到标准 ajax 来做到这一点)。
我确实想到的一个想法是 ngOnDestroy 可以将“标记”传递给 API,然后它可以将该对象标记为“正在处理”。当列表组件执行调用时,它可以检查每个对象以查看它是否具有该标记,并为处于该状态的任何对象显示“刷新陈旧数据”按钮(无论如何,99% 的时间都只是单个项目,用户编辑的最新一篇)。与仅将异步调用更改为同步调用相比,这似乎是一种糟糕的解决方法,并且需要大量额外的代码。
我目前正在尝试让 Angular 应用程序在用户尝试离开我的页面时进行 API 服务调用。通过关闭选项卡/窗口,或输入外部 URL。
我已经尝试实现几种不同的方法,我在这里看到的关于计算器溢出问题的描述,但似乎都没有达到预期的效果。有些人提到了同步 ajax 请求,这些请求已经或正在被 Chrome 上的 onbeforeunload 弃用。其他人建议使用 XMLHttpRequests,它们似乎遭受了同样的命运。我曾尝试@HostListener('window:onbeforeunload', ['$event'])在 HTML 中使用
, 和等价物(window:beforeunload)="doBeforeUnload($event)",但都拒绝合作。我可以让 console.logs 显示出来,但 API 永远不会收到任何注销用户的调用。我也使用过navigator.sendBeacon,尽管它的函数返回 true,表明作业已发送到浏览器队列,但什么也没有实现。
目前,注销功能是这样的:
userLogout(): Observable<any> {
return this.apiService.get('/Account/Logout/');
}
Run Code Online (Sandbox Code Playgroud)
反过来,它是一个通用的 http get 函数:
get<T>(url: string, options?: { params: HttpParams }): Observable<any> {
return this.httpRequest<T>('get', url, null, options ? options.params : null);
}
Run Code Online (Sandbox Code Playgroud)
使用 HttpInterceptor 添加完整 url。注销功能本身正在工作,因为它用于菜单选项,手动使用时按预期工作。所以函数应该不是问题。
我试图做的就是以同步或异步方式调用 userLogout 函数,并通知后端用户已离开。
我正在使用 HostListener 来检测用户何时重新加载或关闭浏览器窗口。目的是#1 检查当前用户是否拥有记录上的“正在编辑”锁,#2 如果是,则调用可观察对象来更新数据库。(注意:我已经使用 CanDeactivate 实现了用于导航离开组件的锁定系统。HostListener 的使用专门用于重新加载或关闭浏览器窗口)。
根据这个类似的问题,'window:unload'是一个仅同步事件,因此我无法在主机侦听器的主体中使用异步 API 调用。
然而,根据 Mozilla 的说法,所接受的解决方案XMLHttpRequest()正在被弃用。
注意:从 Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27)、Blink 39.0 和 Edge 13 开始,主线程上的同步请求已被弃用,因为它们会对用户体验产生负面影响。
我需要一个更可靠的解决方案。有没有办法在 Angular 中发送同步 api 调用来解决这个限制?或者是否有另一种方法可以确保 API 调用在浏览器重新加载或关闭之前完成?
// @HostListener allows guard against browser refresh, close, etc.
@HostListener('window:unload', ['$event'])
beforeUnloadHander($event) {
// Check if Is Being Edited must be removed
if (this.mustReleaseIsBeingEdited()) {
this.updateIsBeingEditedSub = this.updateIsBeingEdited$(true).subscribe(result => {
return true;
}, err => { …Run Code Online (Sandbox Code Playgroud) 我有一个 Angular2 应用程序,我想在用户关闭浏览器窗口时执行一些逻辑。我正在使用浏览器窗口的beforeunload事件。我在 TypeScript 类构造函数中放置了以下代码:
export class MyAngularComponent implements OnInit, OnDestroy {
callServer()
{
//Logic to call the server
}
constructor(private updateServiceFactory: UpdateService) {
window.onbeforeunload = function(e){
this.callServer(); //this does not work
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在 this.callServer() 行中收到编译错误。错误显示“类型 'Window' 上不存在属性 'callServer'”。我知道匿名函数上下文中的“this”指的是 Window 对象。
问题:如何从匿名函数内部调用 callServer() 方法?
angular ×4
javascript ×4
browser ×1
disconnect ×1
events ×1
jquery ×1
onunload ×1
rxjs ×1
sendbeacon ×1
settimeout ×1
socket.io ×1
synchronous ×1
typescript ×1