为什么不推荐使用window.showModalDialog?用什么代替?

Ori*_*iol 27 javascript privileges modal-dialog showmodaldialog window.open

我正在开发一个使用的GreaseMonkey脚本window.showModalDialog.

但在完成之前,我发现Firefox 29警告:

不推荐使用window.showModalDialog().请改用window.open().如需更多帮助, 请访问https://developer.mozilla.org/en-US/docs/Web/API/Window.open

但问题是window.open需要UniversalBrowserWrite特权才能打开模态窗口window.open.

那么,为什么被window.showModalDialog弃用?有没有不需要特权的API?

注意:我不想要一个虚假的模态对话框(比如jQuery的一个),我需要一个暂停JavaScript执行的真实模态.

Ori*_*iol 25

为什么不推荐使用window.showModalDialog?

来自http://tjvantoll.com/2012/05/02/showmodaldialog-what-it-is-and-why-you-should-never-use-it/,

一般来说,将本机对话框实现放入浏览器的想法是一个非常好的主意,但这window.showModalDialog是一个糟糕的实现,充满了问题和糟糕的浏览器支持.(......)

请注意,(...)[使用模式对话框showModalDialog]是一个完整的HTML文档,而不是注入的片段.这是一个特征window.showModalDialog.它实际上只是两个完全独立的窗口相互通信.事实上,你有两个独立的窗口和DOM,这意味着你不必担心JS和DOM冲突,如果你有很多错误的JavaScript与杂乱的全局范围,这是很有吸引力的.但大多数情况下,这只会增加不必要的复杂性,使浏览器实现变得复杂,并导致许多错误.(......)

虽然模态对话框阻止用户与原始窗口交互很重要,但是没有理由不允许用户与其他选项卡或本机浏览器控件(后退/前进,收藏夹,地址栏等)进行交互.(...)这对最终用户来说实际上是一个很大的麻烦.(......)

调试体验window.showModalDialog非常糟糕.(...)你基本上被迫像1999年那样发出警报,以确定发生了什么.(......)

目前没有主要的移动浏览器支持window.showModalDialog,所以如果您正在寻找任何类型的平板电脑/移动支持,您需要远离.

用什么代替?

HTML5引入了新<dialog>元素,可用于显示对话框,包括模态对话框.

例如:

<dialog id="myDialog">
    Foo bar
    <button id="hide">Close</button>
</dialog>
<button id="show">Show Dialog</button>
Run Code Online (Sandbox Code Playgroud)
var dialog = document.getElementById('myDialog');  
document.getElementById('show').onclick = function() {  dialog.showModal();  };  
document.getElementById('hide').onclick = function() {  dialog.close();      };
Run Code Online (Sandbox Code Playgroud)

演示

问题是:

  • 浏览器支持目前可以忽略不计,但有一个polyfill.
  • 它不会暂停 JS执行.


niu*_*ech 5

如果您仍想使用此解决方案,可以使用我的showModalDialog polyfill using <dialog>tag.


Tre*_*ode 3

目前,如果您不想使用权限并想使用模态窗口,最好的方法是使用jQuery UI Dialog或类似的东西。

  • @Oriol为什么你希望js执行暂停?难道你不能在回调被调用之前不做任何事情吗? (3认同)
  • 我将 jquery ui 方法与 iframe 一起使用,我从父级设置了dialogArguments 属性。之前在 showModalDialog 返回后执行的并且基于弹出窗口返回值的任何代码,我都更改为位于匿名函数内,该函数作为回调传递给对话框方法,以便在对话框关闭时执行。在对话框的关闭事件处理程序中,我提取了 returnValue 属性中的内容。这样,对话框中的页面以及之前暂停的代码不需要任何修改。 (2认同)