Слушатель события выгрузки JavaScript Vaadin не срабатывает

У меня есть приложение 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();");

Когда я ухожу со своей веб-страницы, например, закрывая вкладку, я получаю всплывающее окно с подтверждением, как я и хотел. Однако, если я нажму «Да», страница закроется, но мое событие «выгрузить» не сработает. Когда я нажимаю соответствующую кнопку «Стоп», очистка работает правильно, поэтому я знаю, что эта часть в порядке.

Из того, что я читал, все основные браузеры поддерживают onunload (я пробовал Firefox, Chrome, Safari и Opera). Что еще интереснее, если я использую следующий код, то мой closeListener срабатывает на слушателе «beforeunload», но не на слушателе «unload»:

JavaScript.getCurrent().execute(
    "function closeListener() { catchClose(); } " +
    "window.addEventListener('beforeunload', closeListener); " +
    "window.addEventListener('unload', closeListener);"
);

Итак, мой вопрос: по какой причине прослушиватель unload не срабатывает? Является ли этот метод хорошим и надежным способом выполнения операции очистки?

Примечание. Ниже приведен обратный вызов моей функции для операции очистки при закрытии веб-страницы на случай, если это окажет какое-либо влияние на прослушиватель «выгрузки». Я вообще не получаю распечатку, так что это означает, что функция «catchClose» не вызывается.

JavaScript.getCurrent().addFunction("catchClose", arguments -> {
    System.out.println("catchClose callback from " + Page.getCurrent().getWebBrowser().getBrowserApplication());
    presenter.webPageClosed();
});

Редактировать: в результате дальнейшего расследования на самом деле выясняется, что метод выгрузки очень редко срабатывает правильно, хотя я пока не могу точно определить, когда и почему он это делает. Кроме того, я обнаружил, что если я помещаю точку останова в свою функцию closeListener, она вызывается, и моя выгрузка работает абсолютно нормально.

Изменить: теперь мне кажется, что код работает для Safari, Firefox и Opera, но не для Chrome. Я подозреваю, что это связано с побочным эффектом от моего вопрос, который я сейчас решил.


person Lewis Jacobs    schedule 08.06.2016    source источник


Ответы (1)


Я нашел решение своей проблемы.

Я подозреваю, что большая часть этой проблемы была решена решением моя другая связанная проблема, связанная с помещением определенных частей кода в синхронные методы. После устранения этой проблемы метод выгрузки работал в большинстве браузеров, которые я тестировал. Однако Chrome все еще работал и запускал событие выгрузки только при закрытии браузера, а не при закрытии вкладки. Добавление прослушивателя «скрытия страницы» означает, что закрытие вкладки Chrome теперь работает должным образом.

Таким образом, комбинация событий 'unload' и 'pagehide', по-видимому, работает во всех браузерах и (на данный момент для меня) кажется надежной, и моя очистка всегда выполняется, когда пользователь покидает страницу. страница.

person Lewis Jacobs    schedule 10.06.2016