我有一个应用程序,无论用户如何退出页面,都需要清理进程。我正在使用JavaScript来检测用户何时通过选项卡或浏览器关闭退出页面,并显示弹出窗口以确保他们知道当前进程将被停止。这个问题只关注弹出窗口,我只想澄清为什么我需要弹出窗口!
当用户按下按钮以启动该过程时,将调用以下代码:
JavaScript.getCurrent().execute(
"var beforeCloseListener = function (e) { var e = e || window.event; var message = " + LEAVE_PAGE_MESSAGE + "; if(e) e.returnValue = message; return message; } " +
"window.addEventListener('beforeunload', beforeCloseListener);"
);
当用户尝试关闭浏览器时,此代码会创建一个弹出窗口。优秀!下面的屏幕截图显示我可以在Chrome开发者工具中找到该方法。
Chrome Developer Tools javascript search 1st try
但是,如果用户决定重新启动浏览器并导航到同一页面,然后再次单击该按钮,当他们尝试关闭浏览器时,弹出窗口不会显示它们。
这个代码肯定会被再次调用,但javascript似乎并没有被附加。在Chrome开发者工具中,我在搜索时无法再看到该方法。
Chrome Developer Tools javascript search 2nd try
我对Vaadin和JavaScript的了解相当初学,所以我可能会在这里的生命周期中遗漏一些东西,但是我的问题是,为什么第二次JavaScript不会被编译到我的应用程序中,但是第一次完美地工作?我觉得我在这里缺少一些Vaadin功能。
如果我执行或不调用相应的removeEventListener方法,则此行为似乎相同。虽然在my other, related question中,但我认为我的removeEventListener没有被正确触发。
注意:在我测试过的浏览器中,这种行为是相同的; Firefox,Chrome,Safari和Opera。
答案 0 :(得分:0)
这可能是一个很长的拍摄,但几个月前我和Vaadin有同样的问题。对我有用的是将函数赋值给变量,然后将其传递给另一个函数。将您的代码更改为此代码并尝试:
JavaScript.getCurrent().execute(
"someGlobal = function beforeCloseListener(e) { var e = e || window.event; var message = " + LEAVE_PAGE_MESSAGE + "; if(e) e.returnValue = message; return message; } " +
"window.addEventListener('beforeunload', someGlobal);"
);
答案 1 :(得分:0)
我现在找到了问题的答案。基本上,我在ScheduledExecutorService中调用了Vaadin的JavaScript.exectute()方法。 JavaScript不喜欢异步调用,所以我在UI.getCurrent()。access()块中调用了所需的方法。我的印象是,这会导致我需要在UI线程上同步运行javascript代码。显然事实并非如此。
将我的javascript.execute()调用移出执行程序并进入主线程已经解决了我的问题,因为在我的情况下我的JavaScript可以同步运行。我将更多地研究UI.access()方法,看看我所期望的行为是否有效,如果没有,是否有更好的替代方法让JavaScript在异步环境中运行。如果我发现有用的话,我希望将这些信息添加到我的答案中。