I have a button that when clicked opens a new tab via the following code:
const childWindow = window.open('myFile.html', 'my-target');
if (childWindow) {
childWindow.addEventListener('load', () => {
console.log('Hello World');
}
}
When the window opens the first time, "Hello World" is printed. When the button is clicked again the same window is refreshed, but nothing is printed. The child window isn't null
, it just isn't catching the load event.
How do I get the window to refresh on click and also execute the event listener code on load?
This is in Chrome v134.
That's because at the time your event listener is added, the other tab hasn't navigated yet. So you are adding a new event listener to the previous Window
that's gonna be destroyed right after, not on the new one which will fire the event.
window.open()
does return a WindowProxy
object, which does point to whatever the current Window
is at the time you access it. So when you call the second open()
(with the target argument), the WindowProxy
object is the same, but it will act on a different Window
based on when you access it. It's a bit similar to the case of an <iframe>
element, which would also have its contentWindow
point to different Window
objects during its content navigation. And this navigation is asynchronous, so the switch of Window
objects won't happen right away.
Unfortunately there doesn't seem to be great solutions (I can think of) for your case, so the best is probably to have the popup window let its opener
know that it's loaded from its side directly instead of listening from the opener side.
Note that the specs authors are well aware of this restriction and are working on improving it in a modernized version of window.open()
, which hopefully may come to life someday.