簡體   English   中英

從window.open返回一個值

[英]Return a value from window.open

我們最近發現Chrome不再支持window.showModalDialog,這是有問題的,因為我們的企業應用程序使用此方法。

顯然,有一個短期解決方法可以讓你恢復showModalDialog,但它涉及修改注冊表,這對我們普通用戶來說太復雜(而且有風險)。 因此,我不是這種解決方法的忠實粉絲。

長期解決方案顯然是刪除對這個過時方法的所有調用,並用一個方便的jQuery插件替換它們(例如VistaPrint的Skinny Modal Dialog插件 。順便提一句其他建議也是如此)。

我們使用模態對話框的典型場景是在執行無法撤消的操作之前詢問用戶是/否確認,要求用戶在繼續操作之前同意條款和條件等。通常情況下onclick事件為“是”或模態對話框中的“確定”按鈕如下所示:

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

同樣,“取消”或“否”按鈕如下所示:

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

我們可以從對話框中返回一個值的事實非常方便,因為它允許“父”窗口被通知用戶是否單擊了“確定”或“取消”按鈕,如下所示:

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

該方法的第四個參數是回調,其中我檢查用戶是否在允許她繼續之前單擊了“確定”按鈕。

我知道這是一個很長的問題,但基本上歸結為:

  1. 您如何看待我提出的解決方案?
  2. 特別是,你認為我能從一個用window.open打開的窗口中獲取returnValue嗎?
  3. 您可以建議的其他替代方案嗎?

我有兩個想法可以幫助你,但第一個與CORS綁定,所以你將無法從不同的域使用它,至少你可以訪問這兩個服務並配置它們。

第一個想法:

第一個與本機api有關 您可以在父窗口上創建一個全局函數,如下所示:

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

正如您所看到的,它會收到一個結果參數,該參數可以保存您需要的布爾值。 您可以使用相同的舊window.open(url)函數打開彈出窗口。 彈出窗口的onlick事件處理程序可能如下所示:

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

第二個想法:解決問題

我得到的另一個想法是使用這個其他本機api在彈出窗口解析時觸發父窗口上的事件(更好地稱為跨文檔消息傳遞)。 所以你可以從父窗口執行此操作:

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

通過這種方式,您正在偵聽此窗口上的任何已發布消息,並檢查附加到消息的數據是否為 (用戶在彈出窗口中單擊“確定”)或false (用戶在彈出窗口中單擊“取消”)。

在彈出窗口中,您應該向父窗口發布消息,在對應時附加truefalse值:

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

我認為這個解決方案完全符合您的需求。

編輯我寫道,第二個解決方案也與CORS綁定,但深入挖掘我意識到跨文檔消息傳遞與CORS無關

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM