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」事件的組合似乎在所有瀏覽器上班,(對我來說,截至目前)似乎是可靠的,而當用戶離開時一直執行我清理頁。