我有一个 Vaadin 7 应用程序,我需要可靠地检测用户离开或导航离开页面,以便执行一些清理操作。
我的目标是让页面在浏览器/选项卡关闭时弹出一个确认对话框,如果用户选择离开页面,那么此时我会执行清理操作。
我对 JavaScript 相当缺乏经验,但据我发现“onbeforeunload”和“onunload”是可以使用的函数。
此时,我进入页面时使用以下代码:
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};"
);
然后,当我单击界面上的“开始”按钮开始操作时:
JavaScript.getCurrent().execute("addCloseListenersGlobal();");
当我离开网页时,例如通过关闭选项卡,我会看到一个确认弹出窗口,正如我想要的那样。但是,如果我单击"is",页面将关闭,但我的“卸载”事件不会触发。当我单击相应的“停止”按钮时,清理工作正常,因此我知道该部分没问题。
据我所知,主要浏览器都支持 onunload(我尝试过 Firefox、Chrome、Safari 和 Opera)。更有趣的是,如果我使用以下代码,那么我的 closeListener 将在“beforeunload”监听器上触发,但不会在“unload”监听器上触发:
JavaScript.getCurrent().execute(
"function closeListener() { catchClose(); } " +
"window.addEventListener('beforeunload', closeListener); " +
"window.addEventListener('unload', closeListener);"
);
所以我的问题是,“卸载”监听器不触发的原因可能是什么?此方法是执行清理操作的良好且可靠的方法吗?
注意:下面是我在网页关闭时进行清理操作的函数回调,以防对“卸载”监听器产生任何影响。我根本没有打印出来,这意味着“catchClose”函数没有被调用。
JavaScript.getCurrent().addFunction("catchClose", arguments -> {
System.out.println("catchClose callback from " + Page.getCurrent().getWebBrowser().getBrowserApplication());
presenter.webPageClosed();
});
编辑:通过进一步调查,实际上似乎卸载方法偶尔会正确触发,尽管我还无法确定它何时以及为何会这样做。另外,我发现如果我在“closeListener”函数中放置一个断点,它就会被调用,并且我的卸载工作绝对正常。
编辑:对我来说,现在看来代码适用于 Safari、Firefox 和 Opera,但不适用于 Chrome。我怀疑这是由于 my related question 的副作用造成的我现在已经解决了。
最佳答案
我已经找到了问题的解决方案。
我怀疑这个问题的大部分已经通过my other related issue的解决方案解决了其中涉及将代码的某些部分放入同步方法中。解决此问题后,卸载方法适用于我测试过的大多数浏览器。然而,Chrome 仍在运行,只会在浏览器关闭时触发卸载事件,而不是在选项卡关闭时触发卸载事件。添加“pagehide”监听器似乎意味着 Chrome 标签页关闭现在可以正常执行。
因此,“卸载”和“页面隐藏”事件的组合似乎适用于所有浏览器,并且(到目前为止对我来说)似乎是可靠的,并且我的清理始终在以下情况下执行用户离开页面。
关于javascript - Vaadin JavaScript 卸载事件监听器未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37700512/