1. 程式人生 > >高版本chrome不再支援window.showmodaldialog 的臨時替換方案【用window.open】

高版本chrome不再支援window.showmodaldialog 的臨時替換方案【用window.open】

接管別人的專案,因開發時用了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();
}