現代瀏覽器對 window.open() 行為有諸多限制,以防止其被濫用。瀏覽器多內建有快顯封鎖器 (Popup Blocker),只要 window.open() 不是從點擊等直接使用者行為(Direct User Action)事件呼叫,預設就會被封鎖,使用者必須提供站台白名單逐一開放。新朋友可能不知道為什麼要加上這條限制,但有經歷過不小心點開網頁,螢幕瞬間被十幾個啪啪啪廣告影片視窗佔滿的朋友,肯定知道這個防護機制有多重要。

但這幾天發現 Chrome/Edge 有個有趣行為,發現 F12 偵錯會讓 Button Click 中的 window.open() 失效,用以下影片示範:

展示影片

結論,在 Click 事件中設中斷點停下來沒事,但中斷期間只要點選操作 F12 開發者工具,甚至只是滑鼠移到變數上看變數值(推測判斷依據是操作焦點由頁面移到 F12 工具),之後再執行 window.open() 都會被視為非來自直接使用者行為而被封鎖。細想不難理解其邏輯,但最初發現偵錯讓程式壞掉時有點一頭霧水。

本次多學到一個小技巧,有些使用者會沒注意到地址列的「已封鎖快顯」提示,我們可以在 JavaScript 中偵測到 window.open() 失敗,加入更明顯的提示:

<!DOCTYPE html>
<html>
    <body>
        <button onclick="testWinOpen()">Test window.open()</button>
        <script>
            function testWinOpen() {
                // 模擬一段邏輯動態組裝 url
                let host = 'blog.darkthread.net';
                let queryString = '_=' + new Date().getTime();
                // 開發者在此設定中斷點﹐用開發工具觀察變數
                let url = 'https://' + host + (queryString ? '?' : '') + queryString;
                let hnd = window.open(url, '_blank', 'popup=yes');
                if (!hnd) {
                    let div = document.createElement('div');
                    div.style = 'position:absolute;top:3px;right:3px;opacity:0.6;background-color:purple;color:white;padding:6px;';
                    div.innerText = "開啟新視窗時遭快顯封鎖";
                    document.body.appendChild(div);
                }
            }
        </script>
    </body>
</html>


Comments

Be the first to post a comment

Post a comment