2014年的某一天,chrome升级后,突然发现某个在用的系统不能弹出模态窗口了,查找各种资料后确认新版本(可能为Chrome 37+)确实把这个支持去掉了,有这么坑人的吗!?为避免大家少走弯路,特发布此文提供确认躺枪和解决办法。
问题重现
弹出窗口编码:
|
var
obj
=
new
Object
(
)
;
var
retval
=
window
.
showModalDialog
(
"request.aspx"
,
obj
,
"dialogWidth=500px;dialogHeight=300px"
)
;
if
(
retval
==
null
)
{
.
.
.
}
else
{
.
.
.
}
|
浏览器异常:
|
Uncaught
TypeError
:
undefined
is
not
a
function
|
如果出现这个异常,很不幸你已经躺枪了。关于这个问题可以看这里:
http://windowsitpro.com/blog/google-kills-showmodaldialog-api-chrome-37-and-does-evil-exchange-owa
http://www.infoq.com/news/2014/09/chrome-showmodaldialog
其中有些临时解决办法,但貌似showModalDialog不会回来了。
问题解决
常见的弹出窗口有div模拟或者用window.open代替,对于一个已经在用的系统来说,采用div方式转换成本较高,采用window.open改动会更少一些,但也会丢失其模态性。
这里采用简单的window.open方案,毕竟替换成本低很多。针对上文中提到的showModalDialog使用方式,替换为:
|
var
iWidth
=
500
;
var
iHeight
=
300
;
var
iTop
=
(
window
.
screen
.
availHeight
-
30
-
iHeight
)
/
2
;
var
iLeft
=
(
window
.
screen
.
availWidth
-
10
-
iWidth
)
/
2
;
var
win
=
window
.
open
(
"request.aspx"
,
"弹出窗口"
,
"width="
+
iWidth
+
", height="
+
iHeight
+
",top="
+
iTop
+
",left="
+
iLeft
+
",toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no,alwaysRaised=yes,depended=yes"
)
;
|
采用这种方式就可以打开一个和之前使用showModalDialog差不多的窗口。但是怎么返回值呢?
在弹出页面中有两种方式:
1、直接设置父窗口的DOM对象的值。
|
window
.
opener
.
document
.
getElementById
(“
parentWindowControlId”
)
.
value
=
"数据"
;
|
父窗口中应该有一个id为parentWindowControllId的DOM元素。
2、调用父窗口中的Javascript函数,由父窗口进行相应的处理。
|
var
obj
=
{
id
:
"id"
,
name
:
"name"
}
;
window
.
opener
.
DoAfterXXX
(
obj
)
;
|
父窗口提供一个DoAfterXXX的函数就可以了。