从window.open返回一个值 [英] Return a value from window.open

查看:424
本文介绍了从window.open返回一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近发现,Chrome不再支持window.showModalDialog,因为我们的企业应用程序使用这种方法,所以这存在问题。



显然,短期解决方法是允许您恢复showModalDialog,但它涉及修改注册表,这对我们的普通用户来说太复杂(且风险)。因此,我不是这个解决方案的忠实粉丝。



长期解决方案显然是移除对这个过时方法的所有调用,并用一个方便的jQuery插件替换它们例如VistaPrint的 Skinny Modal Dialog插件,其他建议也欢迎采用这种方式) p>

我们使用模态对话框的典型场景是在执行无法撤消的操作之前询问用户是/否确认,要求用户同意以前的条款和条件通常情况下,模式对话框中的是或确定按钮上的onclick事件如下所示:

  window.returnValue = true; 
window.close();

同样,取消或否按钮如下所示:

  window.returnValue = false; 
window.close();

我们可以从对话框中返回一个值的事实非常方便,因为它允许父窗口被通知用户是否点击了Ok或Cancel按钮,如下所示:

  var options =中心:1;状态:1;菜单栏:0;工具栏:0; dialogWidth:875; dialogHeight:650像素; 
var termsOfServiceAccepted = window.showModalDialog(myUrl,null,options);
if(termsOfServiceAccepted){
... proceed ...
}

我将要提到的showModalDialog的最后一件事是,即使对话框中显示的文档来自不同的域,它也可以很好地工作。我们通常从 http://the-client.com 运行JavaScript,但服务条款网页的内容为从 http://the-enterprise-vendor.com



我需要一个临时解决方案,我可以在长期解决方案的同时尽快部署。这里是我的标准:


  • 现有JavaScript中的最小代码更改
  • 弹出窗口必须是能够将值返回给父。通常这个值是一个布尔值,但它可以是任何简单类型(例如:string,int等)。即使内容的URL来自不同的域,
  • 解决方案也必须工作。
  • li>


以下是我到目前为止的内容:

1)我的JavaScript:

 函数OpenDialog(url,width,height,callback)
{
var win = window.open(url,MyDialog,宽度,高度,menubar = 0,toolbar = 0);
var timer = setInterval(function()
{
if(win.closed)
{
clearInterval(timer);
var returnValue = win。 returnValue;
callback(returnValue);
}
},500);

$ / code>

正如您在这种方法中看到的那样,我尝试使弹出窗口通过隐藏菜单和工具栏,看起来类似于对话框,我每隔500毫秒设置一次时间以检查用户是否关闭了窗口,如果是,请获取'returnValue'并调用回调。



2)用以下代码替换showModalDialog的所有调用:

  OpenDialog myUrl,875,650,function(termsOfServiceAccepted)
{
if(termsOfServiceAccepted)
{
... proceed ....
}
} );

该方法的第四个参数是回调函数,用于检查用户是否点击了确定按钮,然后让她继续。



我知道这是一个很长的问题,但基本上归结为:

  • 您如何看待我提出的解决方案?

  • 特别是,您认为我可以从window.open打开的窗口中获得returnValue吗?

  • 其他或者您可以提出建议?
  • 与CORS绑定在一起,所以你不能从不同的域使用它,至少你可以访问这两个服务并配置它们。



    第一个想法:



    第一个涉及到原生api 。您可以在父窗口中创建一个像这样的全局函数:
    $ b $ pre $ window.callback = function(result){
    //代码
    }

    正如你所看到的,它收到了一个 em>参数,它可以容纳你需要的布尔值。您可以使用相同的旧的 window.open(url)功能打开弹出窗口。弹出窗口的onlick事件处理函数可能如下所示:

      function(){
    //做任何你想做的事。
    window.opener.callback(true); //或false
    }

    第二个想法:解决问题



    我得到的另一个想法是使用这个原生api 在弹出窗口解析时触发父窗口上的事件(更好地称为跨文档消息传递)。所以你可以从父窗口中做到这一点:

      window.onmessage = function(e){
    if(e .data){
    //代码为true
    } else {
    //代码为false
    }
    };

    通过这种方式,您可以收听此窗口上发布的任何消息,并检查数据是否附加到消息是 true (用户在弹出窗口中单击确定)或 false (用户在弹出窗口中单击取消)。



    在弹出窗口中,当对应时,您应该向父窗口发送一条消息,附加一个 true false 值:

      window.opener.postMessage(true,'*'); //或false 

    我认为这个解决方案完全符合您的需求。



    编辑
    我写到第二个解决方案也与CORS绑定,但深入挖掘
    我意识到跨文档消息传递并不受限制到CORS

    We recently discovered that Chrome no longer supports window.showModalDialog which is problematic because our enterprise application uses this method.

    There is, apparently, a short term workaround that allows you to restore showModalDialog but it involves modifying the registry which is too complicated (and risky) four our average user. Therefore I'm not a big fan of this workaround.

    The long term solution is obviously to remove all calls to this obsolete method and replace them with a convenient jQuery plugin (such as VistaPrint's Skinny Modal Dialog plugin, for example. Other suggestions are welcome by the way).

    The typical scenario we use the modal dialog is to ask the user for Yes/No confirmation before executing an action that cannot be undone, ask the user to agree to terms and condition before proceeding, etc. Typically the onclick event on the "Yes" or "Ok" button in the modal dialog looks like this:

    window.returnValue = true;
    window.close();
    

    Similarly, the "Cancel" or "No" button looks like this:

    window.returnValue = false;
    window.close();
    

    The fact that we can return a value from the dialog is very convenient because it allows the "parent" window to be notified whether the user has clicked the "Ok" or the "Cancel" button like so:

    var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
    var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
    if (termsOfServiceAccepted) {
        ... proceed ...
    }
    

    The last thing I'm going to mention about the showModalDialog is that it works great even when the document displayed in the dialog is from a different domain. It's very common for us to have our javascript running from http://the-client.com but the "Terms of Service" web page is from http://the-enterprise-vendor.com

    I need a temporary solution that I can deploy ASAP while we work on the long term solution. Here are my criteria:

    • minimal code change in existing JavaScript
    • the pop up window must be able to return a value to the "parent". Typically this value is a Boolean but it could be any simple type (e.g.: string, int, etc.)
    • solution must work even if the URL of the content is from different domain

    Here's what I have so far:

    1) Add the following method in my JavaScript:

    function OpenDialog(url, width, height, callback)
    {
        var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
        var timer = setInterval(function ()
        {
            if (win.closed)
            {
                clearInterval(timer);
                var returnValue = win.returnValue;
                callback(returnValue);
            }
        }, 500);
    }
    

    As you can see in this method, I try to make the pop up window look as similar to a dialog as possible by hiding the menu and the toolbar, I setup a time every 500 milliseconds to check if the window has been closed by the user and if so, get the 'returnValue' and invoke a callback.

    2) replace all calls to showModalDialog with the following:

    OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
    {
        if (termsOfServiceAccepted)
        {
            ... proceed ....
        }
    });
    

    The fourth parameter to the method is the callback where I check if the user has clicked the "Ok" button before allowing her to proceed.

    I know it's a long question but basically it boils down to:

    1. What do you think of the solution I propose?
    2. In particular, do you think I'll be able to get a returnValue from a window that was opened with window.open?
    3. Any other alternative you can suggest?

    解决方案

    I have two ideas that could help you but the first one is tied to CORS, so you won't be able to use it from different domains at least you can access both services and configure them.

    FIRST IDEA:

    The first one is related to this native api. You could create on the parent window a global function like this:

    window.callback = function (result) {
        //Code
    }
    

    As you can see it receives a result argument which can hold the boolean value you need. The you could open the popup using the same old window.open(url) function. The popup's onlick event handler could look like this:

    function() {
        //Do whatever you want.
        window.opener.callback(true); //or false
    }
    

    SECOND IDEA: Solves the problem

    The other idea I got is to use this other native api to trigger an event on the parent window when the popup resolves (better known as cross-document messaging). So you could do this from the parent window:

    window.onmessage = function (e) {
        if (e.data) {
            //Code for true
        } else {
            //Code for false
        }
    };
    

    By this way you are listening to any posted message on this window, and checking if the data attached to the message is true (the user clicks ok in the popup) or false (the user clicks cancel in the popup).

    In the popup you should post a message to the parent window attaching a true or a false value when corresponds:

    window.opener.postMessage(true, '*'); //or false
    

    I think that this solution perfectly fits your needs.

    EDIT I have wrote that the second solution was also tied to CORS but digging deeper I realized that cross-document messaging isn't tied to CORS

    这篇关于从window.open返回一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆