アラート、確認、ポップアップにwindow.showmodaldialog
を使用する巨大なWebアプリケーションがあります。 Chromeバージョン37以降、この呼び出しは無効になっています。
Chromeの最新バージョンでwindow.showmodaldialog
を動作させるための簡単な回避策はありますか?
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をページヘッダーに配置すると、動作するようです。ブラウザが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>
この記事( window.showModalDialogが非推奨になったのはなぜですか?代わりに何を使用しますか? )は、showModalDialogが非推奨になったことを示唆しているようです。
非常に優れた、機能する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
Window.returnValueプロパティは、window.open()を使用してウィンドウを開いているときは直接機能しませんが、window.showModalDialog()を使用しているときは機能します
したがって、あなたの場合、あなたがやろうとしていることを達成するための2つのオプションがあります。
オプション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に置き換える の方法に関する記事をご覧ください。
(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);
}
}
私は良い仕事をしていると思われるポリフィルを使用しています。
非推奨の機能を一時的に有効にしようとはしません。 showModalDialog のMDNドキュメントによると、既にポリフィル Githubで利用可能 があります。
これを使用してwindows.showModalDialog
をユーザースクリプトとしてレガシーエンタープライズアプリケーションに追加しましたが、ソースにアクセスできる場合はHTMLの先頭に追加することもできます。
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);
}
}
}
はい、廃止されました。昨日コードを書き換えて、代わりにWindow.openとPostMessageを使用しました。
Window.showModalDialogは非推奨です(削除の意図:window.showModalDialog()、WebプラットフォームからshowModalDialogを削除)。 [...]最新の計画は、Chromium 37でshowModalDialogの削除を行うことです。これは、機能がOpera 24およびChrome 37でなくなることを意味します。九月に。[...]