使用Prototype时窗口已经存在的Javascript window.open观察

时间:2022-10-22 15:26:01

I've come across an odd scenario in which window.open() is not triggering the 'load' event if the actual window is already on the screen.

我遇到了一个奇怪的场景,如果实际窗口已经在屏幕上,window.open()不会触发'load'事件。

Synopsis
I have a button that when clicked runs some javascript and opens a page in a new window. Standard code that any JS developer has seen. When the method (part of a larger class) is called, it checks if it has a reference to the window (this.preview_window). If so, it will run this.up, it will try and open it again. Once it is open, it runs an update method on that window.

概要我有一个按钮,当点击时运行一些JavaScript并在新窗口中打开一个页面。任何JS开发人员都看到的标准代码。当调用方法(较大类的一部分)时,它会检查它是否具有对窗口的引用(this.preview_window)。如果是这样,它将运行this.up,它将尝试再次打开它。一旦打开,它就会在该窗口上运行更新方法。

Problem
If the window does not exist, everything runs as expected. If the window does exist but the class doesn't have a reference to it, then the reference is successfully acquired with window.open(), however the update function doesn't get called.

问题如果窗口不存在,则一切都按预期运行。如果窗口确实存在但类没有对它的引用,则使用window.open()成功获取引用,但是不会调用更新函数。

Relevant Code

// This code is run whenever there is no reference to the window
this.preview_window = window.open('/folder/page.php','page_previewer');
Event.observe(this.preview_window, 'load',this.update.bindAsEventListener(this));

The rest of the code has been tested heavily so I'm fairly confident that I'm missing something in how the load event works. The window.open() and update() functions operate as expected in all cases but this one.

其余的代码已经过大量测试,所以我非常有信心我错过了load事件的工作方式。 window.open()和update()函数在所有情况下都按预期运行,但是这个。

2 个解决方案

#1


I experimented with this a little bit and it seems the problem is something the previous answer had alluded to - if you already have a window open the call to window.open() will not fire the load event. Therefore, you essentially need to refresh the preview window every time the event handler for your button is called in order to make sure that the load event will be fired and therefore your update handler can also be called. Here is the code I used to demonstrate this:

我对此进行了一些实验,似乎问题是前面的答案所暗示的 - 如果你已经打开了一个窗口,那么对window.open()的调用将不会触发load事件。因此,每次调用按钮的事件处理程序时,基本上都需要刷新预览窗口,以确保将触发load事件,因此也可以调用更新处理程序。这是我用来演示这个的代码:

var preview_window;

function openPreviewWindow() {
    if (preview_window) {
        preview_window.close(); //Load will not fire unless we close the window first
    }
    preview_window = window.open('/', 'preview_window');
    Event.observe(preview_window, 'load', function () {
        alert('Updating opened window.');
    }.bindAsEventListener(this));
}

<a href="#" onclick="openPreviewWindow()">Open Preview Window</a>

This may not be terribly enlightening but hopefully it sets you on a more promising path.

这可能不是非常有启发性,但希望它能让你走上更有前途的道路。

#2


I'm guessing that either the child window is in a different domain when the binding happens, or it is loading from cache before the load happens. try putting your binding in a 500ms timeout. If you control the child window's url, it would be easier to call the parent from the child. Alternatively close & re-open.

我猜测绑定发生时子窗口位于不同的域中,或者在加载发生之前从缓存加载。尝试将绑定设置为500毫秒超时。如果您控制子窗口的URL,则更容易从子窗口调用父窗口。或者关闭并重新开放。

if (this.preview_window && !this.preview_window.closed)
  this.preview_window.close();
... open window ... 

#1


I experimented with this a little bit and it seems the problem is something the previous answer had alluded to - if you already have a window open the call to window.open() will not fire the load event. Therefore, you essentially need to refresh the preview window every time the event handler for your button is called in order to make sure that the load event will be fired and therefore your update handler can also be called. Here is the code I used to demonstrate this:

我对此进行了一些实验,似乎问题是前面的答案所暗示的 - 如果你已经打开了一个窗口,那么对window.open()的调用将不会触发load事件。因此,每次调用按钮的事件处理程序时,基本上都需要刷新预览窗口,以确保将触发load事件,因此也可以调用更新处理程序。这是我用来演示这个的代码:

var preview_window;

function openPreviewWindow() {
    if (preview_window) {
        preview_window.close(); //Load will not fire unless we close the window first
    }
    preview_window = window.open('/', 'preview_window');
    Event.observe(preview_window, 'load', function () {
        alert('Updating opened window.');
    }.bindAsEventListener(this));
}

<a href="#" onclick="openPreviewWindow()">Open Preview Window</a>

This may not be terribly enlightening but hopefully it sets you on a more promising path.

这可能不是非常有启发性,但希望它能让你走上更有前途的道路。

#2


I'm guessing that either the child window is in a different domain when the binding happens, or it is loading from cache before the load happens. try putting your binding in a 500ms timeout. If you control the child window's url, it would be easier to call the parent from the child. Alternatively close & re-open.

我猜测绑定发生时子窗口位于不同的域中,或者在加载发生之前从缓存加载。尝试将绑定设置为500毫秒超时。如果您控制子窗口的URL,则更容易从子窗口调用父窗口。或者关闭并重新开放。

if (this.preview_window && !this.preview_window.closed)
  this.preview_window.close();
... open window ...