19

最近、Chrome が wi​​ndow.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 について最後に言及することは、ダイアログに表示されるドキュメントが別のドメインからのものであっても、うまく機能するということです。http://the-client.comから JavaScript を実行することは非常に一般的ですが、「利用規約」の Web ページは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. あなたが提案できる他の選択肢はありますか?
4

1 に答える 1

24

役立つアイデアが 2 つありますが、最初のアイデアは CORS に関連付けられているため、異なるドメインから使用することはできません。少なくとも、両方のサービスにアクセスして構成することはできます。

最初のアイデア:

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

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

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

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

2 番目のアイデア:問題を解決する

私が得たもう 1 つのアイデアは、この他のネイティブ 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

このソリューションは、お客様のニーズに完全に適合すると思います。

編集 2番目のソリューションもCORSに関連付けられていると書いていますが、さらに深く掘り下げると、クロスドキュメントメッセージングは​​CORSに関連付けられていないことに気付きました

于 2014-09-10T22:48:14.150 に答える