gpt4 book ai didi

java - {Java} Vaadin 14 - 检测用户离开(关闭选项卡、f5 等)

转载 作者:行者123 更新时间:2023-12-04 10:37:49 25 4
gpt4 key购买 nike

我目前正在使用 Vaadin Flow 版本 14 (https://github.com/vaadin/platform/releases/tag/14.0.0)
我运行 Java 版本 1.8.0_231,64 位。

我只是希望能够在用户执行以下任一操作时检测到(在 java 中!):

  • 关闭当前浏览器选项卡(或其浏览器)
  • 在他们的键盘上单击 F5,或在他们的浏览器中按下刷新按钮
  • 单击链接(或其他任何内容),将它们重定向到我的网站

  • 我已经尝试了很多不同的方法来检测这一点。到目前为止,我唯一能够检测到的是当前 VaadinSession 到期时(我可以通过执行 VaadinSession.getCurrent().getSession().setMaxInactiveInterval(15) 来更改)。这使得每个 session 在 15 秒后过期(在我的例子中,15 只是一个测试数字)。

    瓦丁 8 ,我相信你可以做到这一点,它会开箱即用:
            JavaScript.getCurrent().execute(
    "function closeListener() { catchClose(); } " +
    "window.addEventListener('beforeunload', closeListener); " +
    "window.addEventListener('unload', closeListener);"
    );
    JavaScript.getCurrent().addFunction("catchClose", arguments ->
    {
    System.out.println("user has quit :o");
    });

    我不能用这个,因为我用 瓦丁 14 ,而不是 8 .

    我尝试将其添加到我的 View 类中:
        @Override
    protected void onDetach(DetachEvent detachEvent)
    {
    System.out.println("onDetach " + detachEvent);
    }

    它仅在 session 到期时打印此消息(在我的情况下为 15 秒)。即使我不关闭页面。

    我已经尝试实现 离开前观察员 / BeforeLeaveListener 并覆盖这个:
        @Override
    public void beforeLeave(BeforeLeaveEvent beforeLeaveEvent)
    {
    System.out.println("beforeLeave");
    }

    这从不打印。

    我也尝试了所有这些,但他们没有做我需要的:
            VaadinResponse.getCurrent().getService().addUIInitListener(e ->
    {
    System.out.println("1 addUIInitListener : " + e);
    e.getUI().addBeforeLeaveListener(e2 ->
    {
    System.out.println("1.1 addBeforeLeaveListener : " + e2);
    });
    e.getUI().addDetachListener(e2 ->
    {
    System.out.println("1.2 addDetachListener : " + e2);
    });
    });
    VaadinResponse.getCurrent().getService().addServiceDestroyListener(e ->
    {
    System.out.println("2 addServiceDestroyListener : " + e);
    });
    VaadinResponse.getCurrent().getService().addSessionDestroyListener(e ->
    {
    System.out.println("3 addSessionDestroyListener : " + e);
    });
    1 addUIInitListener当用户加载页面时打印。 1.1 addBeforeLeaveListener从不打印。 2 addServiceDestroyListener从不打印。服务与 session 不同。有道理。 1.23 addSessionDestroyListener一段时间后打印。需要15-30秒。

    有没有办法基本上立即检测到这一点? :/

    最佳答案

    检测关闭的 JavaScript 方法仍然有效。

    语法只是稍微改变了一点

    UI.getCurrent().getPage().executeJs("function closeListener() { $0.$server.windowClosed(); } " +
    "window.addEventListener('beforeunload', closeListener); " +
    "window.addEventListener('unload', closeListener);",getElement());


    @ClientCallable
    public void windowClosed() {
    System.out.println("Window closed");
    }

    虽然这不是 100% 防弹的方式,因为我认为并非所有浏览器都以相同的方式工作。例如,上面的代码在 Chrome 中触发了两次,其中只监听 beforeunload足够。

    这允许将 JavaScript 简化为
        UI.getCurrent().getPage().executeJs(
    "window.addEventListener('beforeunload', () => $0.$server.windowClosed()); ",getElement());

    离开前观察员 与导航一起使用。所以如果你使用 路由器链接 或调用 ui.navigate("route")然后 离开前事件 已发送,但在您调用 page.setLocation() 时未发送.

    浏览器可能会因为崩溃而关闭,或者因为其他原因而丢失,然后 beforeunload自然不会发生。最后的手段是基于心跳的检测机制。 IE。在三个丢失的心跳后,Vaadin 服务器将得出浏览器丢失的结论。这自然有延迟,这根本无法避免。

    关于java - {Java} Vaadin 14 - 检测用户离开(关闭选项卡、f5 等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60084612/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com