问题
I have an application which requires a process to be cleaned up regardless of how the user exits the page. I'm using JavaScript to detect when the user exits the page via tab or browser closing, and showing a popup to ensure they know the current process will be stopped. This question regards the pop-up only, I just wanted to clarify why I needed one!
When the user presses a button to start the process, the following code is called:
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);"
);
This code creates a pop-up when the user tries to close the browser. Excellent! The screenshot below shows that I can find the method in Chrome developer tools.
Chrome Developer Tools javascript search 1st try
However, if the user decides to relaunch the browser and navigate to the same page, and click the button again, when they try to close the browser, they are not presented to with the pop-up.
This code is definitely called again, but the javascript does not seem to actually be attached. In Chrome developer tools, I can no longer see the method when I search.
Chrome Developer Tools javascript search 2nd try
My knowledge of both Vaadin and JavaScript is fairly beginner so I could be missing something in the lifecycle of either here, but my question is, why would the JavaScript not be compiled into my application the second time through, but work perfectly the first time? I feel like there is some Vaadin feature I am missing here.
This behaviour seems to be same if I do or do not call the appropriate removeEventListener method. Though as in my other, related question, I don't think my removeEventListener is being fired correctly.
Note: this behaviour is the same across the browsers I have tested on; Firefox, Chrome, Safari and Opera.
回答1:
This might be a long shoot however I had the same problem with Vaadin few months ago. What worked for me was to assign function to the variable and then pass it to the another function. Change your code to this one and have a try:
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);"
);
回答2:
I have now found the answer to my problem. Essentially, I was calling Vaadin's JavaScript.exectute() method from within a ScheduledExecutorService. JavaScript does not like being called asynchronously, so I had the required methods being called within a UI.getCurrent().access() block. I was under the impression that this would cause the javascript code I need to be run synchronously on the UI thread. Apparently this was not the case.
Moving my javascript.execute() calls outside of the executor and into the main thread has solved my problem, as in my case it is acceptable for my JavaScript to be run synchronously. I will be looking more into the UI.access() method to see whether the behaviour I had expected is meant to work and if not, whether there are any better alternatives to get the JavaScript to run in an asynchronous environment. I hope to add this information to my answer if I find anything useful.
来源:https://stackoverflow.com/questions/37704983/vaadin-javascript-popup-only-works-first-time-in-each-session