這個系列是「將 IE-Only 網站翻修到 Chrome/Edge 相容」過程的瑣碎筆記,有參與古蹟維護的朋友請進。

接獲通報,某清嘉慶年間製造的 IE Only 欄位輸入介面,使用 Edge/Chrome 瀏覽會出現關不完的簽核 alert,我用以下網頁重現:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>
    <style>
        table { border-collapse: collapse; font-size: 9pt; }
        td { padding: 7px; border: 1px solid #aaa; }
        td:nth-child(odd) { background-color: #ddd; }
    </style>
</head>

<body>
    <table>
        <tr>
            <td>車牌1</td><td><input id="c1" /></td>
            <td>欄位X</td><td><input id="x1" /></td>
        </tr>
        <tr>
            <td>說明</td>
            <td colspan="3">
                <textarea id="t1" style="width: 100%" rows="4"></textarea>
            </td>
        </tr>
        <tr>
            <td>欄位A</td><td><input id="f1" /></td>
            <td>欄位B</td><td><input id="f2" /></td>
        </tr>
    </table>
    <script>
        $('#c1').blur(function () {
            var inp = $(this);
            if (!/^[-0-9A-Z]{5,7}$/.exec(inp.val())) {
                inp.focus();
                alert("車牌格式有誤,請更正!");
            }
        });
    </script>
</body>

</html>

介面設計概念是在車牌欄位 onblur 事件加入檢核,遇到格式不對以 alert() 提示訊息,並用 focus() 將焦點設回問題欄位,強迫使用者輸入正確格式才准離開。這種操作方式以現在的角度來看有點穾兀,但拿當代建築美學評判古早三合院沒什麼意義,至少程式在 IE 運作無誤,也跑了十幾年。

同樣的網頁移到 Chrome/Edge 執行,便會上演 alert 無窮迴圈的悲劇:

試了一下,將 inp.focus() 移到 alert() 後方一樣會出錯,但拿掉則可避開問題。推敲原因,猜想是在 blur() 事件 focus() 的行為配上 alert 過程焦點曾離開欄位,在 Chrome/Edge 觸發了另一次 blur() 事件。

解決方法不難,實測將 .focus() 包進 setTimeout 執行就行了。

        $('#c1').blur(function () {
            var inp = $(this);
            if (!/^[-0-9A-Z]{5,7}$/.exec(inp.val())) {
                alert("車牌格式有誤,請更正!");
                setTimeout(function() { inp.focus(); }, 50);
            }
        });

這樣就能避開無窮迴圈了。

不過,基於安全理由,Chrome/Edge 會強制在 alert 標題註明 127.0.0.1:5500 顯示127.0.0.1:5500 說 註明來源(就有使用者反映「某某 URL 說」是什麼鬼啦,不能改掉嗎?還真不行哩),Chrome 92 版起甚至禁止 Cross-Site Frame 使用 alert/confirm/prompt,再再顯示 alert 已被屬不合時宜的舊時代產物,建議改用 SweetAlert2 之類的套件取代。而這個「檢核失敗時顯示提示,並將焦點切回問題欄位」的需求,似乎可以考慮寫個小套件讓開發更省力,這個議題會另起一篇來談。


Comments

Be the first to post a comment

Post a comment