web-dev-qa-db-ja.com

window.openから値を返します

最近、Chromeはwindow.showModalDialogをサポートしなくなりました。これは、エンタープライズアプリケーションがこのメソッドを使用しているため問題があります。

どうやら、showModalDialogを復元できる短期的な回避策がありますが、平均的なユーザーでは複雑すぎる(そして危険な)レジストリを変更する必要があります。したがって、私はこの回避策の大ファンではありません。

長期的な解決策は明らかに、この廃止されたメソッドへのすべての呼び出しを削除し、便利なjQueryプラグイン(VistaPrintの Skinny Modal Dialog plugin など。他の提案は歓迎します)に置き換えることです。

モーダルダイアログを使用する一般的なシナリオは、元に戻せないアクションを実行する前にユーザーにYes/Noの確認を求め、続行する前にユーザーに条件に同意するように求めるなどです。通常、「はい」のonclickイベントまたは、モーダルダイアログの[OK]ボタンは次のようになります。

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

同様に、「キャンセル」または「いいえ」ボタンは次のようになります。

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

ダイアログから値を返すことができるという事実は、ユーザーが「OK」または「キャンセル」ボタンをクリックしたかどうかを「親」ウィンドウに通知できるため、非常に便利です。

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

ShowModalDialogについて最後に言及することは、ダイアログに表示されるドキュメントが別のドメインのものであっても、うまく機能するということです。 JavaScriptを http://the-client.com から実行することは非常に一般的ですが、「利用規約」ウェブページは http:// the-enterprise- vendor.com

長期的なソリューションに取り組んでいる間に、できるだけ早く展開できる一時的なソリューションが必要です。私の基準は次のとおりです。

  • 既存のJavaScriptの最小限のコード変更
  • ポップアップウィンドウは、「親」に値を返すことができる必要があります。通常、この値はブール値ですが、任意の単純なタイプ(たとえば、string、intなど)にすることもできます
  • コンテンツのURLが異なるドメインからのものであっても、ソリューションが機能する必要がある

ここに私が持っているものがあります:

1)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);
}

このメソッドでわかるように、メニューとツールバーを非表示にして、ポップアップウィンドウをダイアログにできるだけ似せて表示しようとします。ユーザーがウィンドウを閉じたかどうかを確認するために500ミリ秒ごとに時間を設定します。その場合、「returnValue」を取得してコールバックを呼び出します。

2)showModalDialogのすべての呼び出しを次のように置き換えます。

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

メソッドの4番目のパラメーターはコールバックで、ユーザーが続行する前にユーザーが[OK]ボタンをクリックしたかどうかを確認します。

私はそれが長い質問であることを知っていますが、基本的には次のように要約します:

  1. 私が提案する解決策についてどう思いますか?
  2. 特に、window.openで開かれたウィンドウからreturnValueを取得できると思いますか?
  3. 他に提案できるものはありますか?
15
desautelsj

私はあなたを助けることができる2つのアイデアを持っていますが、最初のアイデアはCORSに関連付けられているので、少なくとも両方のサービスにアクセスしてそれらを設定することができる異なるドメインからそれを使用することはできません。

最初のアイデア:

最初のものはこれに関連しています native api 。次のようなグローバル関数を親ウィンドウに作成できます。

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

ご覧のとおり、必要なブール値を保持できるresult引数を受け取ります。同じ古いwindow.open(url)関数を使用してポップアップを開くことができます。ポップアップのonlickイベントハンドラは次のようになります。

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

SECOND IDEA:問題を解決します

私が得た他のアイデアは、この他の native api を使用して、ポップアップが解決されたときに親ウィンドウでイベントをトリガーすることです(クロスドキュメントメッセージングとして知られています)。したがって、親ウィンドウからこれを行うことができます:

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

この方法で、このウィンドウで投稿されたメッセージを聞いて、メッセージに添付されたデータがtrue(ユーザーがポップアップで[OK]をクリックする)かfalse(ユーザーがポップアップでキャンセルをクリックします)。

ポップアップで、trueまたはfalse値が対応する場合、親ウィンドウにメッセージを投稿する必要があります。

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

このソリューションはあなたのニーズに完全に合っていると思います。

[〜#〜] edit [〜#〜]2番目のソリューションもCORSに関連付けられていたが、さらに深く掘り下げて、クロスドキュメントメッセージングは​​CORSに関連付けられていません