高版本chrome不再支援window.showmodaldialog 的臨時替換方案【用window.open】
阿新 • • 發佈:2019-01-07
接管別人的專案,因開發時用了showmodaldialog 導致最近很多使用者chrome升級到最新之後 就無法彈窗了。原因是新版chrome[37+]不再支援showmodaldialog。
showmodaldialog 並不是W3C標準內的方法,起源於IE, 當是低版本的firefox也是不支援的,後來不知怎麼了又納入了這個方法。貌似opera和safari都不支援。隨著web標準的日益規範化,估計Firefox 和 IE都不會再支援它了。所以建議經常使用它做資料互動的同學可以拋棄它了,改用js和div封裝的彈窗元件吧。
下面我貼出我解決此問題的方法。
因為我這個專案是巢狀很多iframe的。彈視窗會有資料回傳。彈窗之上又有彈窗也會有值回傳。3級或者更多。所以我把相容的js程式碼寫在一個檔案,所有涉及彈視窗的頁面均呼叫這個指令碼檔案:
common.js
var has_showModalDialog = !!window.showModalDialog;//定義一個全域性變數判定是否有原生showModalDialog方法 if(!has_showModalDialog &&!!(window.opener)){ window.onbeforeunload=function(){ window.opener.hasOpenWindow = false; //彈窗關閉時告訴opener:它子視窗已經關閉 } } //定義window.showModalDialog如果它不存在 if(window.showModalDialog == undefined){ window.showModalDialog = function(url,mixedVar,features){ if(window.hasOpenWindow){ alert("您已經打開了一個視窗!請先處理它");//避免多次點選會彈出多個視窗 window.myNewWindow.focus(); } window.hasOpenWindow = true; if(mixedVar) var mixedVar = mixedVar; //因window.showmodaldialog 與 window.open 引數不一樣,所以封裝的時候用正則去格式化一下引數 if(features) var features = features.replace(/(dialog)|(px)/ig,"").replace(/;/g,',').replace(/\:/g,"="); //window.open("Sample.htm",null,"height=200,width=400,status=yes,toolbar=no,menubar=no"); //window.showModalDialog("modal.htm",obj,"dialogWidth=200px;dialogHeight=100px"); var left = (window.screen.width - parseInt(features.match(/width[\s]*=[\s]*([\d]+)/i)[1]))/2; var top = (window.screen.height - parseInt(features.match(/height[\s]*=[\s]*([\d]+)/i)[1]))/2; window.myNewWindow = window.open(url,"_blank",features); } }
執行彈出的當前頁的方法用例:(有返回值)
function selectHotel(){ url = 'hotel/listHotelForChoose.action'; var hotelIdList = window.showModalDialog(url, "hotel", "dialogWidth:1020px;dialogHeight:500px;help:no;resizable:no;center:yes;scroll:yes;status:no"); if(!has_showModalDialog) return;//chrome 返回 因為showModalDialog是阻塞的 open不一樣; $("#content").append(hotelIdList); } function selectHotelChrome(option){//為開啟的視窗定義方法,讓開啟的視窗關閉時通過window.opener賦值回來並執行 $("#content").append(option); }
子視窗這樣呼叫:
function chooseHotels() {
/*
*省略了自己的業務.......
*/
if (window.opener != undefined) { //forchrome
window.opener.selectHotelChrome(contentIds); //關閉前呼叫父視窗方法
}
else {
window.returnValue = contentIds;
}
window.close();
}