Подтвердить что ты не робот

Как я могу сделать window.showmodaldialog работать в хроме 37?

У нас есть огромное веб-приложение, в котором мы используем 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;

    }

Просто поместите этот код в главный раздел страницы.

4b9b3361

Ответ 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>

Ответ 2

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

Он устарел по дизайну. Вы можете повторно включить поддержку showModalDialog, но только временно - до мая 2015 года. Используйте это время для создания альтернативных решений.

Вот как это сделать в Chrome для Windows. Откройте редактор реестра (regedit) и создайте следующий ключ:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\EnableDeprecatedWebPlatformFeatures

Под клавишей EnableDeprecatedWebPlatformFeatures создайте строковое значение с именем 1 и значением ShowModalDialog_EffectiveUntil20150430. Чтобы убедиться, что политика включена, перейдите в URL-адрес хром://.


ОБНОВЛЕНИЕ: Если выше не работает для вас, есть еще один способ попробовать.
  • Загрузите шаблоны Chrome ADM из http://www.chromium.org/administrators/policy-templates
  • Политика извлечения и импорта, относящаяся к вашему языку (например, windows\adm\en-US\chrome.adm. Вы можете импортировать либо через gpedit.msc, либо с помощью этих утилит в Домашних версиях окон: http://blogs.technet.com/b/fdcc/archive/2008/05/07/lgpo-utilities.aspx)
  • В разделе "Административные шаблоны" найдите шаблон Google Chrome и включите "Включить устаревшие флагов веб-платформы".
  • Откройте эту функцию и добавьте ключ "ShowModalDialog_EffectiveUntil20150430".

Ответ 4

Очень хорошее и работоспособное решение 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

Ответ 5

Я бы не попытался временно включить устаревшую функцию. Согласно документации MDN для showModalDialog, уже существует polyfill доступно на Github.

Я просто использовал это, чтобы добавить windows.showModalDialog к устаревшему корпоративному приложению в качестве пользователя, но вы также можете добавить его в голову HTML, если у вас есть доступ к источнику.

Ответ 7

Создать кросс-браузер 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);
        }
    }
}

Ответ 8

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

Ответ 9

Свойство 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);

Ознакомьтесь со статьей о том, как заменить window.showModalDialog на window.open.

Ответ 10

Window.showModalDialog устарел (намерение удалить: window.showModalDialog(), Удаление showModalDialog из Интернета Платформа). [...] Последний план - вывести showModalDialog в Chromium 37. Это означает, что функция будет отсутствовать в Opera 24 и Chrome 37, оба из которых должны быть выпущены в сентябре. [...]

Ответ 11

Да, он устарел. Вчера потратил переписывающий код на использование Window.open и PostMessage.