Nous avons une énorme application web où nous utilisons window.showmodaldialog
pour les alertes, confirmations et popups. Depuis Chrome version 37, cet appel a été désactivé.
Existe-t-il une solution rapide pour que window.showmodaldialog
fonctionne dans la dernière version de Chrome?
J'ajoute ici une solution de contournement pour window.showmodaldialog, bien que cette solution ne soit pas parfaite car elle ne gênera pas l'exécution du code comme le faisait showmodaldialog, mais cela ouvrira les fenêtres contextuelles. .
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;
}
Il suffit de mettre ce code dans la section d'en-tête de la page.
Je mets le javascript suivant dans l'en-tête de page et cela semble fonctionner. Il détecte lorsque le navigateur ne prend pas en charge showModalDialog et associe une méthode personnalisée qui utilise window.open, analyse les spécifications de dialogue (hauteur, largeur, défilement, etc.), se centre sur ouvreur et redéfinit le focus vers la fenêtre (si le focus est perdu). ). En outre, il utilise l'URL comme nom de fenêtre afin qu'une nouvelle fenêtre ne soit pas ouverte à chaque fois. Si vous transmettez des arguments window au modal, vous devrez écrire du code supplémentaire pour résoudre ce problème. Le popup n'est pas modal mais au moins vous ne devez pas changer beaucoup de code. Peut-être besoin de travail en fonction de votre situation.
<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>
Cet article ( Pourquoi (window.showModalDialog est déconseillé? Que faut-il utiliser à la place? ) semble suggérer que showModalDialog a été déconseillé.
Une très bonne solution javascript qui fonctionne est fournie ici: https://github.com/niutech/showModalDialog
Personnellement, je l'ai utilisé, fonctionne comme avant pour les autres navigateurs et crée une nouvelle boîte de dialogue pour le chrome navigateur.
Voici un exemple d'utilisation:
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
La propriété window.returnValue ne fonctionne pas directement lorsque vous ouvrez une fenêtre à l'aide de window.open () alors que cela fonctionne lorsque vous utilisez window.showModalDialog ()
Donc, dans votre cas, vous avez deux options pour réaliser ce que vous essayez de faire.
Option 1 - Utiliser window.showModalDialog ()
Dans votre page parent
var answer = window.showModalDialog(<your page and other arguments>)
if (answer == 1)
{ do some thing with answer }
et à l'intérieur de votre page enfant, vous pouvez utiliser le window.returnValue directement comme
window.returnValue = 'value that you want to return';
showModalDialog interrompt l'exécution du code JavaScript jusqu'à ce que la boîte de dialogue soit fermée et peut obtenir une valeur de retour de la boîte de dialogue ouverte lors de sa fermeture. showModalDialog est qu'il n'est pas pris en charge par de nombreux navigateurs modernes . En revanche, window.open ouvre simplement une fenêtre de manière asynchrone (l'utilisateur peut accéder à la fois à la fenêtre parente et à la fenêtre ouverte). Et l'exécution de JavaScript continuera immédiatement. Ce qui nous amène à l'option 2
Option 2 - Utiliser window.open () Dans votre page parent, écrivez une fonction qui traite de l'ouverture de votre boîte de dialogue.
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);
}
}
});
}
}
Et chaque fois que vous souhaitez utiliser, ouvrez une boîte de dialogue. Écrivez un rappel qui traite la valeur de retour et transmettez-le en tant que paramètre à la fonction openDialog
function callback(returnValue){
if(returnValue){
do something Nice with the returnValue
}}
Et en appelant la fonction
openDialog(<your page>, 'width px', 'height px', callbak);
Découvrez un article sur la façon de remplacez window.showModalDialog par 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);
}
}
J'utilise un polyfill qui semble faire du bon travail.
Je n'essaierais pas d'activer temporairement une fonctionnalité obsolète. Selon la documentation MDN pour showModalDialog , il existe déjà un polyfill disponible sur Github .
Je viens de l'utiliser pour ajouter windows.showModalDialog
vers une application d'entreprise existante sous forme de script utilisateur, mais vous pouvez évidemment l'ajouter également dans la tête du code HTML si vous avez accès au code source.
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);
}
}
}
Oui, c'est obsolète. Hier, nous avons réécrit le code pour utiliser Window.open et PostMessage à la place.
Window.showModalDialog est obsolète (intention de supprimer: window.showModalDialog (), suppression de showModalDialog de la plate-forme Web). [...] Le dernier plan consiste à supprimer le retrait de showModalDialog dans Chromium 37. Cela signifie que la fonctionnalité sera supprimée Opera 24 et Chrome 37, qui devraient tous deux sortir en septembre. [...]