Chromium 新的彈窗機制以及 HTML 的 元素

自 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-polyfilldom

一個最簡單的例子:網站

<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();
};複製代碼

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);
}複製代碼

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 方案時,咱們應該老是使用最新標準。

相關文章
相關標籤/搜索