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

IT技术 javascript modal-dialog privileges window.open showmodaldialog
2021-02-03 11:53:03

我正在开发一个使用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 执行。

4个回答

为什么不推荐使用 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>
var dialog = document.getElementById('myDialog');  
document.getElementById('show').onclick = function() {  dialog.showModal();  };  
document.getElementById('hide').onclick = function() {  dialog.close();      };

演示

问题是:

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

如果你想仍然使用这个解决方案,你可以使用我的showModalDialog polyfill using <dialog>tag。

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

@Oriol 为什么要暂停 js 执行?在调用回调之前你不能做任何事情吗?
2021-03-16 11:53:03
但是 jQuery 的模态对话框被称为modal但它不是modal我需要停止 JavaScript 执行。
2021-03-29 11:53:03
你能应用 jQuery 的 when() 和 then() 方法来模拟某种“暂停”吗?
2021-03-29 11:53:03
在我以前的项目中,我对 window.open() 和权限有同样的问题。因此,我们决定使用 jQuery。为了防止执行 js,我可以建议使用 trow() 函数或类似的东西。
2021-04-05 11:53:03
我将 jquery ui 方法与 iframe 一起使用,我从父级设置了 dialogArguments 属性。在从 showModalDialog 返回之后之前执行的任何代码,并且基于弹出窗口的返回值,我更改为在我传递给我的对话框方法的匿名函数中作为在对话框关闭时执行的回调。在对话框的关闭事件处理程序中,我提取了 returnValue 属性中的内容。这样对话框中的页面以及之前暂停的代码不需要任何修改。
2021-04-09 11:53:03

要阻止脚本执行,请使用while (true) { }. 事实上,这同样是糟糕的行为,这是showModalDialog他们删除showModalDialog.

此外,“模态”和“阻止脚本执行”不是一回事。“模态”只是意味着在其他一切之上,阻止您与这些事物进行交互。所以 jQuery UI 对话框是模态的,它们只是不阻止脚本执行。

您无法停止此循环执行,因为 js 是单线程的。打开window.open窗户仍然使用相同的线程,并且会完全冻结(您甚至可能永远不会看到它们)
2021-04-08 11:53:03
嗯,但是while (true) { }CPU 密集型,不是吗?如果我这样做,页面(甚至浏览器)将冻结,因此对话框也将无法使用。我只想暂停页面,而不是对话框。
2021-04-10 11:53:03