简体   繁体   English

Vaadin JavaScript卸载事件监听器未触发

[英]Vaadin JavaScript unload event listener not firing

I have a Vaadin 7 application where I need to reliably detect a user leaving or navigating away from a page in order to carry out some cleanup. 我有一个Vaadin 7应用程序,我需要可靠地检测用户离开或导航离开页面以执行一些清理。

My aim is to have the page pop up a confirmation dialog on browser/tab close, and if the user chooses to leave the page, then at that point I perform the cleanup operation. 我的目标是让页面弹出一个关闭浏览器/选项卡的确认对话框,如果用户选择离开页面,那么我在那时执行清理操作。

I am fairly inexperienced at JavaScript, but from what I have discovered 'onbeforeunload' and 'onunload' are the functions to use. 我对JavaScript很缺乏经验,但是从我发现的'onbeforeunload'和'onunload'是要使用的函数。

At this point in time, I am using the following code when I enter the page: 此时,我在进入页面时使用以下代码:

JavaScript.getCurrent().execute(
    "beforeCloseListenerGlobal = function beforeCloseListener (e) {\nvar e = e || window.event;\nvar message = " + LEAVE_PAGE_MESSAGE + ";\nif(e) e.returnValue = message;\nreturn message;\n};\n" +
    "closeListenerGlobal = function closeListener () {\ncatchClose();\n};\n" +
    "addCloseListenersGlobal = function addCloseListeners () {\nwindow.addEventListener('beforeunload', beforeCloseListenerGlobal);\nwindow.addEventListener('unload', closeListenerGlobal);\n};\n" +
    "removeCloseListenersGlobal = function removeCloseListeners () {\nwindow.removeEventListener('beforeunload', beforeCloseListenerGlobal);\nwindow.removeEventListener('unload', closeListenerGlobal);\n};"       
);

Then, when I click the "Start" button on my interface to start the operation: 然后,当我单击界面上的“开始”按钮开始操作时:

JavaScript.getCurrent().execute("addCloseListenersGlobal();");

When I navigate away from my webpage, by closing the tab for example, I get a confirmation pop-up, just as I want. 当我离开我的网页时,通过关闭标签,我会得到一个确认弹出窗口,就像我想要的那样。 However, if I click Yes, the page closes but my 'unload' event does not fire. 但是,如果我单击是,页面将关闭,但我的'卸载'事件不会触发。 When I click the respective "Stop" button, the cleanup works correctly, so I know that part is fine. 当我单击相应的“停止”按钮时,清理工作正常,所以我知道该部分没问题。

From what I've read the major browsers all support onunload (I've tried Firefox, Chrome, Safari and Opera). 从我读过的主要浏览器都支持onunload(我尝试过Firefox,Chrome,Safari和Opera)。 More interestingly, if I use the following code, then my closeListener fires on the 'beforeunload' listener, but not on the 'unload' listener: 更有趣的是,如果我使用以下代码,那么我的closeListener将触发'beforeunload'侦听器,但不会触发'unload'侦听器:

JavaScript.getCurrent().execute(
    "function closeListener() { catchClose(); } " +
    "window.addEventListener('beforeunload', closeListener); " +
    "window.addEventListener('unload', closeListener);"
);

So my question is, what could be the reason for the 'unload' listener not to fire? 所以我的问题是,“卸载”听众不能解雇的原因是什么? Is this method a good and reliable way to perform a cleanup operation? 这种方法是一种执行清理操作的好方法吗?

Note: below is my function callback for the cleanup operation on webpage close, in case that would have any effect on the 'unload' listener. 注意:下面是我在网页关闭时清理操作的函数回调,以防对'unload'监听器产生任何影响。 I do not get a print out at all, so that implies the "catchClose" function is not called. 我根本没有打印出来,所以这意味着没有调用“catchClose”函数。

JavaScript.getCurrent().addFunction("catchClose", arguments -> {
    System.out.println("catchClose callback from " + Page.getCurrent().getWebBrowser().getBrowserApplication());
    presenter.webPageClosed();
});

Edit: Through further investigation it actually appears as though the unload method very occasionally does fire correctly, though I cannot pinpoint when and why it does that just yet. 编辑:通过进一步的调查,实际看起来好像卸载方法偶尔会正确启动,但我无法确定它何时以及为什么会这样做。 Also, I have discovered that if I put a breakpoint inside my "closeListener" function, it gets called, and my unload works absolutely fine. 另外,我发现如果我在“closeListener”函数中放置一个断点,它会被调用,我的卸载工作绝对正常。

Edit: For me it now appears as if the code works for Safari, Firefox and Opera, but not Chrome. 编辑:对我来说,它现在看起来好像代码适用于Safari,Firefox和Opera,但不适用于Chrome。 I suspect it is due to a side effect from my related question which I have now resolved. 我怀疑这是由于我现在解决的相关问题的副作用。

I have found the solution to my problem. 我找到了解决问题的方法。

I suspect that most of this issue was solved by the solution to my other related issue which involved putting certain parts of code into synchronous methods. 我怀疑这个问题的大部分是通过我的其他相关问题的解决方案解决的,该问题涉及将某些代码部分放入同步方法中。 After fixing this issue, the unload method worked across most of the browsers I have tested on. 解决此问题后,卸载方法适用于我测试过的大多数浏览器。 However, Chrome was still playing up and would only fire the unload event on browser close, and not on tab close. 但是,Chrome仍在播放,只会在浏览器关闭时触发卸载事件,而不会在关闭标签上触发。 Adding in a 'pagehide' listener seems to mean that Chrome tab closing is now acting appropriately. 添加'pagehide'监听器似乎意味着Chrome标签关闭现在正在正常运行。

So, a combination of 'unload' and 'pagehide' events seems to work across all browsers , and (as of now for me) appears to be reliable, and my cleanup is always performed when the user leaves the page. 因此, 'unload'和'pagehide'事件的组合似乎适用于所有浏览器 ,并且(截至目前为止 )似乎是可靠的,并且我的清理总是在用户离开页面时执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM