Javascript 如何使 window.showmodaldialog 在 chrome 37 中工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25663053/
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-08-22 21:40:05  来源:igfitidea点击:

How can I make window.showmodaldialog work in chrome 37?

javascriptjqueryasp.netgoogle-chromecross-browser

提问by Anubrij Chandra

We have a huge web application where we use window.showmodaldialogfor alerts, confirmations and popups. Since Chrome version 37 this call has been disabled.

我们有一个巨大的网络应用程序,window.showmodaldialog用于警报、确认和弹出窗口。自 Chrome 37 版起,此调用已被禁用。

Is there any quick workaround to make window.showmodaldialogwork in the latest version of Chrome?

是否有任何快速解决方法可以window.showmodaldialog在最新版本的 Chrome 中工作?

I am adding here a workaround for window.showmodaldialog, although this is not a perfect workaround because this will not break the code execution as showmodaldialog was doing, instead this will open the popups.

我在这里添加了一个 window.showmodaldialog 的解决方法,虽然这不是一个完美的解决方法,因为这不会像 showmodaldialog 那样破坏代码执行,而是会打开弹出窗口。

window.showModalDialog = function (url, arg, feature) {
        var opFeature = feature.split(";");
       var featuresArray = new Array()
        if (document.all) {
           for (var i = 0; i < opFeature.length - 1; i++) {
                var f = opFeature[i].split("=");
               featuresArray[f[0]] = f[1];
            }
       }
        else {

            for (var i = 0; i < opFeature.length - 1; i++) {
                var f = opFeature[i].split(":");
               featuresArray[f[0].toString().trim().toLowerCase()] = f[1].toString().trim();
            }
       }



       var h = "200px", w = "400px", l = "100px", t = "100px", r = "yes", c = "yes", s = "no";
       if (featuresArray["dialogheight"]) h = featuresArray["dialogheight"];
        if (featuresArray["dialogwidth"]) w = featuresArray["dialogwidth"];
       if (featuresArray["dialogleft"]) l = featuresArray["dialogleft"];
        if (featuresArray["dialogtop"]) t = featuresArray["dialogtop"];
        if (featuresArray["resizable"]) r = featuresArray["resizable"];
       if (featuresArray["center"]) c = featuresArray["center"];
      if (featuresArray["status"]) s = featuresArray["status"];
        var modelFeature = "height = " + h + ",width = " + w + ",left=" + l + ",top=" + t + ",model=yes,alwaysRaised=yes" + ",resizable= " + r + ",celter=" + c + ",status=" + s;

        var model = window.open(url, "", modelFeature, null);

       model.dialogArguments = arg;

    }

Just put this code in the head section of page.

只需将此代码放在页面的头部部分即可。

回答by Steve Osborne

I put the following javascript in the page header and it seems to work. It detects when the browser does not support showModalDialog and attaches a custom method that uses window.open, parses the dialog specs (height, width, scroll, etc.), centers on opener and sets focus back to the window (if focus is lost). Also, it uses the URL as the window name so that a new window is not opened each time. If you are passing window args to the modal you will need to write some additional code to fix that. The popup is not modal but at least you don't have to change a lot of code. Might need some work for your circumstances.

我将以下 javascript 放在页眉中,它似乎有效。它检测浏览器何时不支持 showModalDialog 并附加一个使用 window.open 的自定义方法,解析对话框规范(高度、宽度、滚动等),将焦点放在 opener 上并将焦点设置回窗口(如果焦点丢失) )。此外,它使用 URL 作为窗口名称,因此不会每次都打开一个新窗口。如果您将窗口参数传递给模态,您将需要编写一些额外的代码来解决这个问题。弹出窗口不是模态的,但至少您不必更改大量代码。可能需要根据您的情况进行一些工作。

<script type="text/javascript">
  // fix for deprecated method in Chrome 37
  if (!window.showModalDialog) {
     window.showModalDialog = function (arg1, arg2, arg3) {

        var w;
        var h;
        var resizable = "no";
        var scroll = "no";
        var status = "no";

        // get the modal specs
        var mdattrs = arg3.split(";");
        for (i = 0; i < mdattrs.length; i++) {
           var mdattr = mdattrs[i].split(":");

           var n = mdattr[0];
           var v = mdattr[1];
           if (n) { n = n.trim().toLowerCase(); }
           if (v) { v = v.trim().toLowerCase(); }

           if (n == "dialogheight") {
              h = v.replace("px", "");
           } else if (n == "dialogwidth") {
              w = v.replace("px", "");
           } else if (n == "resizable") {
              resizable = v;
           } else if (n == "scroll") {
              scroll = v;
           } else if (n == "status") {
              status = v;
           }
        }

        var left = window.screenX + (window.outerWidth / 2) - (w / 2);
        var top = window.screenY + (window.outerHeight / 2) - (h / 2);
        var targetWin = window.open(arg1, arg1, 'toolbar=no, location=no, directories=no, status=' + status + ', menubar=no, scrollbars=' + scroll + ', resizable=' + resizable + ', copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
        targetWin.focus();
     };
  }
</script>

回答by Yuriy Galanter

From http://codecorner.galanter.net/2014/09/02/reenable-showmodaldialog-in-chrome/

来自http://codecorner.galanter.net/2014/09/02/reenable-showmodaldialog-in-chrome/

It's deprecated by design. You can re-enable showModalDialog support, but only temporarily – until May of 2015. Use this time to create alternative solutions.

它已被设计弃用。您可以重新启用 showModalDialog 支持,但只能暂时启用 - 直到 2015 年 5 月。利用这段时间创建替代解决方案。

Here's how to do it in Chrome for Windows. Open Registry Editor (regedit) and create following key:

这是在 Windows 版 Chrome 中执行此操作的方法。打开注册表编辑器 (regedit) 并创建以下项:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures

Under the EnableDeprecatedWebPlatformFeatureskey create a string value with name 1and value of ShowModalDialog_EffectiveUntil20150430. To verify that the policy is enabled, visit chrome://policy URL.

EnableDeprecatedWebPlatformFeatures键下创建一个名称1和值为 的字符串值ShowModalDialog_EffectiveUntil20150430。要验证策略是否已启用,请访问 chrome://policy URL。



UPDATE:更新:如果以上方法对您不起作用,请尝试另一种方法。

  1. Download Chrome ADM templates from http://www.chromium.org/administrators/policy-templates
  2. Extract and import policy relevant to your locale (e.g. windows\adm\en-US\chrome.adm. You can import either via gpedit.mscor using these utilities on Home editions of windows: http://blogs.technet.com/b/fdcc/archive/2008/05/07/lgpo-utilities.aspx)
  3. Under “Adminstrative Templates” locate Google Chrome template and enable “Enable Deprecated Web Platform Feautes”.
  4. Open the feature and add “ShowModalDialog_EffectiveUntil20150430″ key.
  1. http://www.chromium.org/administrators/policy-templates下载 Chrome ADM 模板
  2. 提取和导入与您的区域设置相关的策略(例如 windows\adm\en-US\chrome.adm。您可以通过gpedit.msc或使用 Windows 家庭版上的这些实用程序导入:http: //blogs.technet.com/b/fdcc /archive/2008/05/07/lgpo-utilities.aspx)
  3. 在“管理模板”下找到 Google Chrome 模板并启用“启用已弃用的 Web 平台功能”。
  4. 打开功能并添加“ShowModalDialog_EffectiveUntil20150430”键。

回答by Nigel Ellis

This article (Why is window.showModalDialog deprecated? What to use instead?) seems to suggest that showModalDialog has been deprecated.

这篇文章(为什么不推荐使用 window.showModalDialog?用什么代替?)似乎暗示 showModalDialog 已被弃用。

回答by Benster

A very good, and working, javascript solution is provided here : https://github.com/niutech/showModalDialog

这里提供了一个非常好的、有效的 javascript 解决方案:https: //github.com/niutech/showModalDialog

I personnally used it, works like before for other browser and it creates a new dialog for chrome browser.

我个人使用过它,在其他浏览器上的工作方式和以前一样,它为 chrome 浏览器创建了一个新对话框。

Here is an example on how to use it :

这是一个关于如何使用它的示例:

function handleReturnValue(returnValue) {
    if (returnValue !== undefined) {
        // do what you want
    }
}

var myCallback = function (returnValue) { // callback for chrome usage
    handleReturnValue(returnValue);
};

var returnValue = window.showModalDialog('someUrl', 'someDialogTitle', 'someDialogParams', myCallback); 
handleReturnValue(returnValue); // for other browsers except Chrome

回答by Rolf Rodrigo Krueger

Create a cross browser ModalDialog

创建一个跨浏览器的 ModalDialog

function _showModalDialog(url, width, height, closeCallback) {
    var modalDiv,
        dialogPrefix = window.showModalDialog ? 'dialog' : '',
        unit = 'px',
        maximized = width === true || height === true,
        w = width || 600,
        h = height || 500,
        border = 5,
        taskbar = 40, // windows taskbar
        header = 20,
        x,
        y;

    if (maximized) {
        x = 0;
        y = 0;
        w = screen.width;
        h = screen.height;
    } else {
        x = window.screenX + (screen.width / 2) - (w / 2) - (border * 2);
        y = window.screenY + (screen.height / 2) - (h / 2) - taskbar - border;
    }

    var features = [
            'toolbar=no',
            'location=no',
            'directories=no',
            'status=no',
            'menubar=no',
            'scrollbars=no',
            'resizable=no',
            'copyhistory=no',
            'center=yes',
            dialogPrefix + 'width=' + w + unit,
            dialogPrefix + 'height=' + h + unit,
            dialogPrefix + 'top=' + y + unit,
            dialogPrefix + 'left=' + x + unit
        ],
        showModal = function (context) {
            if (context) {
                modalDiv = context.document.createElement('div');
                modalDiv.style.cssText = 'top:0;right:0;bottom:0;left:0;position:absolute;z-index:50000;';
                modalDiv.onclick = function () {
                    if (context.focus) {
                        context.focus();
                    }
                    return false;
                }
                window.top.document.body.appendChild(modalDiv);
            }
        },
        removeModal = function () {
            if (modalDiv) {
                modalDiv.onclick = null;
                modalDiv.parentNode.removeChild(modalDiv);
                modalDiv = null;
            }
        };

    // IE
    if (window.showModalDialog) {
        window.showModalDialog(url, null, features.join(';') + ';');

        if (closeCallback) {
            closeCallback();
        }
    // Other browsers
    } else {
        var win = window.open(url, '', features.join(','));
        if (maximized) {
            win.moveTo(0, 0);
        }

        // When charging the window.
        var onLoadFn = function () {
                showModal(this);
            },
            // When you close the window.
            unLoadFn = function () {
                window.clearInterval(interval);
                if (closeCallback) {
                    closeCallback();
                }
                removeModal();
            },
            // When you refresh the context that caught the window.
            beforeUnloadAndCloseFn = function () {
                try {
                    unLoadFn();
                }
                finally {
                    win.close();
                }
            };

        if (win) {
            // Create a task to check if the window was closed.
            var interval = window.setInterval(function () {
                try {
                    if (win == null || win.closed) {
                        unLoadFn();
                    }
                } catch (e) { }
            }, 500);

            if (win.addEventListener) {
                win.addEventListener('load', onLoadFn, false);
            } else {
                win.attachEvent('load', onLoadFn);
            }

            window.addEventListener('beforeunload', beforeUnloadAndCloseFn, false);
        }
    }
}

回答by Nadeemmnn Mohd

    (function() {
        window.spawn = window.spawn || function(gen) {
            function continuer(verb, arg) {
                var result;
                try {
                    result = generator[verb](arg);
                } catch (err) {
                    return Promise.reject(err);
                }
                if (result.done) {
                    return result.value;
                } else {
                    return Promise.resolve(result.value).then(onFulfilled, onRejected);
                }
            }
            var generator = gen();
            var onFulfilled = continuer.bind(continuer, 'next');
            var onRejected = continuer.bind(continuer, 'throw');
            return onFulfilled();
        };
        window.showModalDialog = window.showModalDialog || function(url, arg, opt) {
            url = url || ''; //URL of a dialog
            arg = arg || null; //arguments to a dialog
            opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles
            var caller = showModalDialog.caller.toString();
            var dialog = document.body.appendChild(document.createElement('dialog'));
            dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
            dialog.innerHTML = '<a href="#" id="dialog-close" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">&times;</a><iframe id="dialog-body" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
            document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
            document.getElementById('dialog-close').addEventListener('click', function(e) {
                e.preventDefault();
                dialog.close();
            });
            dialog.showModal();
            //if using yield
            if(caller.indexOf('yield') >= 0) {
                return new Promise(function(resolve, reject) {
                    dialog.addEventListener('close', function() {
                        var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
                        document.body.removeChild(dialog);
                        resolve(returnValue);
                    });
                });
            }
            //if using eval
            var isNext = false;
            var nextStmts = caller.split('\n').filter(function(stmt) {
                if(isNext || stmt.indexOf('showModalDialog(') >= 0)
                    return isNext = true;
                return false;
            });
            dialog.addEventListener('close', function() {
                var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
                document.body.removeChild(dialog);
                nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue));
                eval('{\n' + nextStmts.join('\n'));
            });
            throw 'Execution stopped until showModalDialog is closed';
        };
    })()

;

**Explanation:
------------**
The best way to deal with showModalDialog for older application conversions is use to `https://github.com/niutech/showModalDialog` inorder to work with show modal dialogs  and if modal dailog has ajax calls you need to create object and set the parameters of function to object and pass below...before that check for browser and set the useragent...example: agentStr = navigator.userAgent; and then check for chrome

var objAcceptReject={}; // create empty object and set the parameters to object and send to the other functions as dialog when opened in chrome breaks the functionality
    function rejectClick(index, transferId) {
        objAcceptReject.index=index;
        objAcceptReject.transferId=transferId;

     agentStr = navigator.userAgent;

                var msie = ua.indexOf("MSIE ");

                if (msie > 0) // If Internet Explorer, return version number
                {
                    var ret = window.showModalDialog("/abc.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {
                        doSomeClick(index);
                    }

                } else if ((agentStr.indexOf("Chrome")) >- 1){
                spawn(function() {

                    var ret = window.showModalDialog("/abcd.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {// create an object and store values in objects and send as parameters
                        doSomeClick(objAcceptReject.index);
                    }

                });

                }
                else {
                    var ret = window.showModalDialog("/xtz.jsp?accept=false",window,"dialogHeight:175px;dialogWidth:475px;scroll:no;status:no;help:no");   

                    if (ret=="true") {
                        doSomeClick(index);
                    }
                }

回答by Kuncheria

The window.returnValue property does not work directly when you are opening a window using window.open() while it does work when you are using window.showModalDialog()

当您使用 window.open() 打开窗口时 window.returnValue 属性不会直接工作,而在您使用 window.showModalDialog() 时它会工作

So in your case you have two options to achieve what you are trying to do.

因此,在您的情况下,您有两种选择来实现您想要做的事情。

Option 1 - Using window.showModalDialog()

选项 1 - 使用 window.showModalDialog()

In your parent page

在您的父页面中

var answer = window.showModalDialog(<your page and other arguments>)
if (answer == 1)
 { do some thing with answer }

and inside your child page you can make use of the window.returnValue directly like

在您的子页面中,您可以直接使用 window.returnValue

window.returnValue = 'value that you want to return';

showModalDialoghalts the executions of the JavaScript until the dialog box is closed and can get a return value from the opened dialog box when its closing.But the problem with showModalDialog is that it is not supported on many modern browsers. In contrast window.open just opens a window asynchronously (User can access both the parent window and the opened window). And the JavaScript execution will continue immediately. Which bring us to Option 2

showModalDialog停止执行 JavaScript,直到对话框关闭,并且可以在关闭时从打开的对话框中获取返回值。但是 showModalDialog 的问题是许多现代浏览器不支持它。相比之下 window.open 只是异步打开一个窗口(用户可以访问父窗口和打开的窗口)。JavaScript 执行将立即继续。这将我们带到了选项 2

Option 2 - Using window.open()In your parent page write a function that deals with opening of your dialog.

选项 2 - 使用 window.open()在您的父页面中编写一个处理对话框打开的函数。

function openDialog(url, width, height, callback){
if(window.showModalDialog){
    options = 'dialogHeight: '+ height + '; dialogWidth: '+ width + '; scroll=no'
    var returnValue = window.showModalDialog(url,this,options);
    callback(returnValue)
}
else {
    options ='toolbar=no, directories=no, location=no, status=yes, menubar=no, resizable=yes, scrollbars=no, width=' + width + ', height=' + height; 
        var childWindow = window.open(url,"",options);
        $(childWindow).on('unload',function(){
            if (childWindow.isOpened == null) {
                childWindow.isOpened = 1;
            }
            else {
                if(callback){
                    callback(childWindow.returnValue);
                }
            }
        });
}

}

}

And whenever you want to use open a dialog. Write a callback that deals with the return value and pass it as a parameter to openDialog function

每当你想使用打开一个对话框。编写一个处理返回值的回调并将其作为参数传递给 openDialog 函数

function callback(returnValue){
if(returnValue){
    do something nice with the returnValue
}}

And when calling the function

当调用函数时

openDialog(<your page>, 'width px', 'height px', callbak);

Check out an article on how to replace window.showModalDialog with window.open

查看关于如何用 window.open 替换 window.showModalDialog的文章

回答by aross

I wouldn't try to temporarily enable a deprecated feature. According to the MDN documentation for showModalDialog, there's already a polyfill available on Github.

我不会尝试暂时启用已弃用的功能。根据showModalDialog的 MDN 文档,Github上已经有一个 polyfill可用

I just used that to add windows.showModalDialogto a legacy enterprise application as a userscript, but you can obviously also add it in the head of the HTML if you have access to the source.

我只是用它windows.showModalDialog作为用户脚本添加到遗留的企业应用程序中,但如果您可以访问源代码,显然您也可以将它添加到 HTML 的头部。

回答by user3722785

The window.showModalDialog is deprecated (Intent to Remove: window.showModalDialog(), Removing showModalDialog from the Web platform). [...]The latest plan is to land the showModalDialog removal in Chromium 37. This means the feature will be gone in Opera 24 and Chrome 37, both of which should be released in September.[...]

window.showModalDialog 已弃用(移除意图:window.showModalDialog(),正在从 Web 平台移除 showModalDialog)。[...]最新计划是在 Chromium 37 中移除 showModalDialog。这意味着该功能将在 Opera 24 和 Chrome 37 中消失,这两个版本都应在 9 月发布。[...]