自 1995 年 JavaScript 诞生之初,就包含了 3 个方法 alert()
、confirm()
和 prompt()
。在随后的 Chrome 版本中,Chrome 团队一直在修改原生弹窗的表现。javascript
可是这种阻断式的弹窗总被各类广告网站恶意使用,由于只要弹窗出现,JavaScript 引擎就会一直等待,知道用户操做。因此这种原生弹窗的最大用处不是用来提示用户信息,而是伤害用户(Tech support scammers use subdomain trick to defeat blocking)。css
所以 Chromium 团队强烈建议你不要使用这类弹窗。html
而弹窗和 onbeforeunload
事件相结合以后那简直就是大杀器,而此类弹窗常常被用来提示浏览者xxxx。前端
Chromium 团队在 Chrome 51 中移除了对 onbeforeunload
弹窗的支持。在此以前 Safari 9.1 和 Firefox 4 早就已经移除了。当咱们在 onbeforeunload
事件中调用 alert
时,会在 devtools 中产生警告:java
Blocked alert('before unload') during beforeunload.
除此以外,alert()
、confirm()
、prompt()
的行为也作了改变,再也不做为顶级的原生弹窗而存在,当弹窗所在的浏览器标签被切走后,它们会自动消失。(Safari 9.1 说:“你怎么到如今才来学啊!”) git
Chromium 在官方博客中说到:github
对于
alert()/confirm()/prompt()
咱们有不少替代的选择。 譬如须要弹个通知消息时(日历应用)能够用Notifications API。 获取用户输入能够用 HTML 中的<dialog>
元素。 对于 XSS proofs-of-concept 则可用console.log(document.origin)
。浏览器
<dialog>
做为 HTML 5.2 的元素,目前除了 Chrome 和 Opara 之外,其它浏览器均未支持。可是 Google 提供了一个 dialog-polyfill。dom
一个最简单的例子:网站
<dialog>This is da dialog!</dialog>
这段 html 什么也不显示,开发者须要使用 javascript 的 API .show()
和 .close()
来控制 dialog 的显示和隐藏。
<dialog> <p>This is da dialog!</p> <button id="close">Close</button> </dialog> <button id="show">Open Dialog!</button>
var dialog = document.querySelector('dialog'); document.querySelector('#show').onclick = function() { dialog.show(); }; document.querySelector('#close').onclick = function() { dialog.close(); };
https://jsfiddle.net/m1dzstxo/
点击按钮会出现一个弹窗(很是丑)
不过 dialog 做为一个 html 标签,是可使用 css 的。咱们给它加一段 css 样式:
dialog { border: 1px solid rgba(0, 0, 0, 0.3); border-radius: 6px; box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); }
https://jsfiddle.net/m1dzstxo/1/
再点击按钮,弹窗了一个稍微漂亮点的弹窗:
咱们还可使用 .showModal()
弹窗一个模态对话框,当咱们关闭弹窗时触发 close
事件。咱们还可使用 ESC 键关闭一个弹窗,此时会触发 cancel
事件。和其它全部事件同样,咱们能够经过调用 event.preventDefault()
来阻止默认行为。
直接弹窗一个模态窗口是不够友好的,有时咱们须要把背景虚化:
经过使用 CSS 的伪元素 ::backdrop
很容易就能够作到:
dialog::backdrop { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.8); }
为何使用 <dialog>
元素而不是第三方的 javascript 库?
我以为二者并不冲突,目前大部分 javascript 库都是使用 <div>
来模拟弹窗,当更多的浏览器开始支持 <dialog>
时,第三方的 javascript 库也会考虑使用 <dialog>
做为首先的弹窗方式的,毕竟 <dialog>
是 HTML 5.2 规范中的。
相比 <div>
而言,<dialog>
更大强大,也更加符合规范。好比 <dialog>
的模态弹窗能够保证即便全屏的状况下,弹窗能够保持在最顶层(top-layer)。top-layer 定义在 whatwg 的 Fullscreen API 中,能够配合伪元素 ::backdrop
以及伪类 :fullscreen
一块儿使用。
开发面向将来的前端,当有 polyfill 方案时,咱们应该老是使用最新标准。