Vaadin JavaScript 弹出窗口仅在每个会话中第一次有效
Vaadin JavaScript popup only works first time in each session
我有一个应用程序,无论用户如何退出页面,它都需要清理一个进程。我正在使用 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 方法,此行为似乎都是一样的。尽管与 中一样,我认为我的 removeEventListener 没有被正确触发。
注意:此行为在我测试过的所有浏览器中都是相同的; Firefox、Chrome、Safari 和 Opera。
这可能是一个长期的尝试,但是几个月前我在使用 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);"
);
我现在找到了问题的答案。本质上,我是从 ScheduledExecutorService 中调用 Vaadin 的 JavaScript.exectute() 方法。 JavaScript 不喜欢被异步调用,所以我在 UI.getCurrent().access() 块中调用了所需的方法。我的印象是这会导致我需要在 UI 线程上同步 运行 的 javascript 代码。显然不是这样。
将我的 javascript.execute() 调用移出执行程序并进入主线程已经解决了我的问题,因为在我的情况下,我的 JavaScript 同步为 运行。我将更多地研究 UI.access() 方法,看看我预期的行为是否有效,如果无效,是否有更好的替代方法来使 JavaScript 变为 运行 在异步环境中。如果我发现任何有用的信息,我希望将此信息添加到我的答案中。
我有一个应用程序,无论用户如何退出页面,它都需要清理一个进程。我正在使用 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 方法,此行为似乎都是一样的。尽管与
注意:此行为在我测试过的所有浏览器中都是相同的; Firefox、Chrome、Safari 和 Opera。
这可能是一个长期的尝试,但是几个月前我在使用 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);"
);
我现在找到了问题的答案。本质上,我是从 ScheduledExecutorService 中调用 Vaadin 的 JavaScript.exectute() 方法。 JavaScript 不喜欢被异步调用,所以我在 UI.getCurrent().access() 块中调用了所需的方法。我的印象是这会导致我需要在 UI 线程上同步 运行 的 javascript 代码。显然不是这样。
将我的 javascript.execute() 调用移出执行程序并进入主线程已经解决了我的问题,因为在我的情况下,我的 JavaScript 同步为 运行。我将更多地研究 UI.access() 方法,看看我预期的行为是否有效,如果无效,是否有更好的替代方法来使 JavaScript 变为 运行 在异步环境中。如果我发现任何有用的信息,我希望将此信息添加到我的答案中。