JavaScript 中弹出窗口的回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10762423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 10:58:15  来源:igfitidea点击:

Callback for a popup window in JavaScript

javascriptcallbackpopupwindow

提问by Miro Hudak

I hope I did my homework well, searching the Internets for the last couple of hours and trying everything before posting here, but I'm really close to call it impossible, so this is my last resort.

我希望我的功课做得很好,在最后几个小时搜索互联网并尝试了一切,然后再在这里发帖,但我真的很接近于说这是不可能的,所以这是我最后的手段。

I want a simple thing (but seems like hard in JavaScript):

我想要一个简单的东西(但在 JavaScript 中似乎很难):

  1. Click button -> Open Window (using window.open)
  2. Perform an action in the popup window and return the value to parent (opener)
  1. 单击按钮 -> 打开窗口(使用 window.open)
  2. 在弹出窗口中执行操作并将值返回给父级(开启者)

But I want to achieve it in a systematic way, having a callback defined for this popup; something like:

但是我想以系统的方式实现它,为此弹出窗口定义一个回调;就像是:

var wnd = window.open(...)
wnd.callback = function(value) {
    console.log(value);
};

I've tried defining the callback property in popup window JS code:

我尝试在弹出窗口 JS 代码中定义回调属性:

var callback = null;

Unfortunately, that does not work, as...

不幸的是,这不起作用,因为......

$('#action').click(function() {
    console.log(callback);
});

... returns just that "null" I set initially.

...仅返回我最初设置的“空”。

I've also tried setting the callback in a parent window after window load (both thru window.onload=... and $(window).ready()), none worked.

我还尝试在窗口加载后在父窗口中设置回调(都通过 window.onload=... 和 $(window).ready()),没有一个工作。

I've also tried defining some method in child window source code to register callback internally:

我还尝试在子窗口源代码中定义一些方法来在内部注册回调:

function registerCallback(_callback)
{
    callback = _callback; // also window.callback = _callback;
}

But with the same result.

但结果相同。

And I don't have any more ideas. Sure, it would be simple setting the value using window.opener, but I'll loose much of a flexibility I need for this child window (actually an asset selector for DAM system).

我没有更多的想法。当然,使用 window.opener 设置值会很简单,但是我会失去这个子窗口(实际上是 DAM 系统的资产选择器)所需的很多灵活性。

If you have some ideas, please share them. Thank you a million!

如果您有一些想法,请分享。谢谢你一百万!

采纳答案by Miro Hudak

After few more hours of experiments, I think, I've found a viable solution for my problem.

经过几个小时的实验,我想,我已经为我的问题找到了一个可行的解决方案。

The point is to reference jQuery from parent window and trigger a jQuery event on this window (I'm a Mac user but I suppose, jQuery has events working cross-platform, so IE compatibility is not an issue here).

关键是从父窗口引用 jQuery 并在此窗口上触发 jQuery 事件(我是 Mac 用户,但我想,jQuery 具有跨平台工作的事件,因此 IE 兼容性在这里不是问题)。

This is my code for click handler on anchor...

这是我在锚点上单击处理程序的代码...

$(this).find('a[x-special="select-asset"]').click(function() {
    var evt = jQuery.Event('assetSelect', {
        url:        'this is url',
        closePopup: true,
    });
    var _parent = window.opener;
    _parent.jQuery(_parent.document).trigger(evt);
});

... and this is the code of event handler:

...这是事件处理程序的代码:

$(document).bind('assetSelect', function (evt) {
    console.log(evt);
});

This solution is fine, if you don't need to distinguish between multiple instances of the asset selection windows (only one window will dispatch "assetSelect" event). I have not found a way to pass a kind of tag parameter to window and then pass it back in event.

这个解决方案很好,如果你不需要区分资产选择窗口的多个实例(只有一个窗口会调度“assetSelect”事件)。我还没有找到将一种标签参数传递给窗口然后在事件中将其传递回的方法。

Because of this, I've chosen to go along with (at the end, better and visually more pleasant) solution, Fancybox. Unfortunately, there is no way - by default - to distinguish between instances either. Therefore, I've extended Fancybox as I've described in my blog post. I'm not including the full text of blog post here, because is not the topic of this question.

正因为如此,我选择了(最后,更好,视觉上更愉快)解决方案,Fancybox。不幸的是,默认情况下也无法区分实例。因此,我扩展了 Fancybox,正如我在博客文章中所描述的那样。我不在这里包括博客文章的全文,因为不是这个问题的主题。

URL of the blog post: http://82517.tumblr.com/post/23798369533/using-fancybox-with-iframe-as-modal-dialog-on-a-web

博文网址:http: //82517.tumblr.com/post/23798369533/using-fancybox-with-iframe-as-modal-dialog-on-a-web

回答by Jeffrey Sweeney

HTML5's postMessagecomes to mind. It's designed to do exactly what you're trying to accomplish: post messages from one window and process it in another.

postMessage想到了HTML5 。它旨在完成您想要完成的工作:从一个窗口发布消息并在另一个窗口中处理它。

https://developer.mozilla.org/en/DOM/window.postMessage

https://developer.mozilla.org/en/DOM/window.postMessage

The caveat is that it's a relatively new standard, so older browsers may not support this functionality.

需要注意的是,它是一个相对较新的标准,因此较旧的浏览器可能不支持此功能。

http://caniuse.com/#feat=x-doc-messaging

http://caniuse.com/#feat=x-doc-messaging



It's pretty simple to use:

使用起来非常简单:

To send a message from the source window:

从源窗口发送消息:

window.postMessage("message", "*");
//'*' is the target origin, and should be specified for security

To listen for messages in a target window:

要在目标窗口中侦听消息:

window.addEventListener
("message", function(e) {
console.log(e.data); //e.data is the string message that was sent.
}, true);