2016-06-08 110 views
1

我有一个Vaadin 7应用程序,我需要可靠地检测用户离开或导航离开页面以执行一些清理。Vaadin JavaScript卸载事件监听器没有触发

我的目标是让页面在浏览器/选项卡关闭时弹出一个确认对话框,如果用户选择离开页面,那么在那时我执行清理操作。

我对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();"); 

当我离开我的网页时,通过关闭标签,例如,我得到一个确认弹出窗口,就像我想的那样。但是,如果我点击是,页面关闭,但我的'卸载'事件不会触发。当我点击相应的“停止”按钮时,清理工作正常,所以我知道该部分是好的。从我读过的主流浏览器都支持onunload(我试过Firefox,Chrome,Safari和Opera)。更有趣的是,如果我用下面的代码,然后在“beforeunload”监听我的closeListener火灾,但不是在“卸载”听众:

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的副作用。

回答

0

我找到了解决我的问题的方法。

我怀疑这个问题的大部分都是通过my other related issue的解决方案解决的,它涉及将某些代码部分放入同步方法中。解决了这个问题后,卸载方法在我测试过的大多数浏览器上都能正常工作。不过,Chrome仍在玩,只能在浏览器关闭时触发卸载事件,而不是在关闭标签页时触发。添加“页面隐藏”侦听器似乎意味着Chrome选项卡关闭现在正在适当地运行。

所以,一个“卸载”和“pagehide”事件的组合似乎在所有浏览器上班,(对我来说,截至目前)似乎是可靠的,而当用户离开时一直执行我清理页。