【问题标题】:How can I make window.showmodaldialog work in chrome 37?如何使 window.showmodaldialog 在 chrome 37 中工作?
【发布时间】:2014-10-29 01:26:18
【问题描述】:

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

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

我在这里添加了 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;

    }

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

【问题讨论】:

标签: javascript jquery asp.net google-chrome cross-browser


【解决方案1】:

我将以下 javascript 放在页面标题中,它似乎可以工作。它检测浏览器何时不支持 showModalDialog 并附加一个使用 window.open 的自定义方法,解析对话框规范(高度、宽度、滚动等),以开启者为中心并将焦点设置回窗口(如果焦点丢失)。此外,它使用 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>

【讨论】:

  • 看来 IE 也有同样的问题。如果我们通过删除第一个 if 来覆盖该函数,则它适用于所有 3 个主要浏览器。
  • jsfiddle 中的任何示例? jsfiddle.net/grj4x5k9 使用 HTML5 对话框 的示例(有这个问题)
【解决方案2】:

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

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

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

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures

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


更新:如果上述方法对您不起作用,请尝试另一种方法。
  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. 在“Adminstrative Templates”下找到 Google Chrome 模板并启用“Enable Deprecated Web Platform Feautes”。
  4. 打开功能并添加“ShowModalDialog_EffectiveUntil20150430”键。

【讨论】:

  • 你知道如何在 Mac 中解决这个问题吗?
  • @sanjeev40084 我自己没试过,但是根据chromium.org/administrators/…在Preference Name下EnableDeprecatedWebPlatformFeatures你设置值&lt;array&gt;&lt;string&gt;ShowModalDialog_EffectiveUntil20150430&lt;/string&gt;&lt;/array&gt;
  • 我相信你应该命名字符串值 ShowModalDialog_EffectiveUntil20150430 而不是 ShowModalDialog_EffectiveUntil201504301。
  • 必须喜欢对 2 岁的答案投反对票而没有任何解释。但是,如果您仍在尝试使用 showModalDialog 并通过投票来发泄您的不满 - 我为您感到难过。
【解决方案3】:

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

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

这是一个如何使用它的例子:

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

【讨论】:

    【解决方案4】:

    这篇文章 (Why is window.showModalDialog deprecated? What to use instead?) 似乎表明 showModalDialog 已被弃用。

    【讨论】:

      【解决方案5】:

      window.returnValue 属性在使用 window.open() 打开窗口时不能直接工作,而在使用 window.showModalDialog() 时它确实有效

      所以在你的情况下,你有两种选择来实现你想要做的事情。

      选项 1 - 使用 window.showModalDialog()

      在你的父页面中

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

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

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

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

      选项 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);
                      }
                  }
              });
      }
      

      }

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

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

      以及调用函数时

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

      查看一篇关于如何replace window.showModalDialog with window.open的文章

      【讨论】:

      • 请不要添加same answer to multiple questions。一旦您获得足够的声誉,就回答最好的一个并将其余的标记为重复项。如果不是重复的,请根据问题调整帖子并标记以取消删除。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        【讨论】:

        • 谢谢这对我有用......我投票给你的答案
        【解决方案8】:

        创建一个跨浏览器的 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);
                }
            }
        }
        

        【讨论】:

        • 我认为您应该明确 IE 路径 (window.showModalDialog()) blocks 直到对话框关闭,而“其他浏览器”路径立即返回。如果您需要阻止行为,这是行不通的。
        • 建议:示例用法jsfiddle 中的任何示例?
        【解决方案9】:
            (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);
                            }
                        }
        

        【讨论】:

          【解决方案10】:

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

          【讨论】:

            【解决方案11】:

            是的,它已被弃用。昨天花了重写代码来改用 Window.open 和 PostMessage。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-10-30
              • 1970-01-01
              相关资源
              最近更新 更多