Как я могу сделать 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;
}
Просто поместите этот код в главный раздел страницы.
Ответы
Ответ 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-адрес хром://.
ОБНОВЛЕНИЕ: Если выше не работает для вас, есть еще один способ попробовать.
Ответ 3
Эта статья (Почему window.showModalDialog устарел? Что использовать вместо?), кажется, что showModalDialog устарел.
Ответ 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, если у вас есть доступ к источнику.
Ответ 6
Я использую polyfill, который, кажется, делает хорошую работу.
https://github.com/niutech/showModalDialog
http://niutech.github.io/showModalDialog/demo.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;">×</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.