Chrome Dev Summit 2018 is happening now and streaming live on YouTube. Watch now.

Chromium 的彈窗機制

JavaScript 彈窗的歷史

JavaScript 誕生於1995年,在最初的版本里便包含了三個掛載到 window 對象上的彈窗方法 alert()confirm(), 和 prompt()

這種阻斷式的彈窗 API 在當時是沒有問題的,但在異步操作流行的今天便不合時宜了。因爲 JavaScript 引擎需要中斷執行來等待用戶的反饋,關鍵這個彈窗是原生的還不是網頁裏的。 正因爲是原生的彈窗,所以經常被利用來 傷害 我們的 用戶

鑑於此,Chromium 團隊強烈建議你不要使用這類彈窗。

替代方案

對於彈窗需求其實我們有很多其他的選擇。

對於 alert()/confirm()/prompt() 我們有很多替代的選擇。 譬如需要彈個通知消息時(日曆應用)可以用 Notifications API。 獲取用戶輸入可以用 HTML 中的 <dialog> 元素 。 對於 XSS proofs-of-concept 則可用 console.log(document.origin)

至於 onbeforeunload 這個事件,它已經變得不可靠了。正如 Ilya Grigorik 所指出的那樣, “在移動端平臺上,你不能指望 pagehidebeforeunloadunload 這些事件會被觸發。” 如果想在此類情況下保存一些數據,可以用 Page Visibility API

變更

Chrome 51 中移除了對 onbeforeunload 的支持。(Safari 9.1 and in Firefox 4 中也移除了的。)

alert()/confirm()/prompt() 的表現進行了改變。不再作爲頂級的原生彈窗而存在,當彈窗所在的瀏覽器標籤被切走後, 他們會自動消失。 (Safari 9.1 已經這樣做了。) 這個變更在 canary 和 dev 版本中全部開啓, 而在 beta 和穩定版中則是部分開啓,但在之後肯定是會全部開啓的。

對於 beforeunload 彈窗,目前的計劃是必需有用戶有相應的交互才讓它顯示。(但 beforeunload 事件的廣播不會受影響。) 這使得 Chromium 在表現上和 Firefox 統一了,後者在 Firefox 44 中做了此項修改。

由於以上這些變更,如果你的站點中使用了彈窗,我們強烈建議你使用上文中提到的備選方案,以免功能受到影響。