首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JavaScript 自定義 Alert 樣式:覆寫 window.alert 實現原生彈窗完美替代方案

     編輯:Java 綜合教學

為什麼原生 alert 無法美化?

window.alert 是瀏覽器原生方法,內部實現為 Native Code,無法獲取、修改其樣式、佈局、按鈕文字。唯一可行路徑:**覆寫 `window.alert`**,用自定義 HTML/CSS/JS 彈窗完全替換。

核心實現步驟

  1. 定義彈窗 HTML 結構:遮罩層 + 彈窗容器 + 訊息區 + 確定按鈕。
  2. 插入 DOM:首次調用時動態創建並 document.body.appendChild()。
  3. 樣式控制:用 element.style.cssText 批量設定,避免 IE8 渲染 Bug。
  4. 事件綁定:確定按鈕點擊 → 移除 DOM、執行回調(如有)。
  5. 覆寫 window.alert:必須在預編譯階段完成,否則覆寫前的調用仍走原生。

完整代碼(純 JS、無依賴、IE8+ 兼容)

;(function (win) {
    // 1. 預編譯階段立即覆寫,確保所有 alert 走自定義邏輯
    var nativeAlert = win.alert;
    win.alert = function (msg) {
        showCustomAlert(String(msg == null ? '' : msg));
    };

    // 2. 單例模式:全頁只有一套 DOM
    var alertBox = null, mask = null, btn = null;

    function ensureDOM() {
        if (alertBox) return;
        mask = document.createElement('div');
        alertBox = document.createElement('div');
        var msgBox = document.createElement('div');
        btn = document.createElement('button');

        // 結構組裝
        alertBox.appendChild(msgBox);
        alertBox.appendChild(btn);
        document.body.appendChild(mask);
        document.body.appendChild(alertBox);

        // 3. 樣式統一用 cssText,解決 IE8 不支援 style.xxx 寫法
        var css = {
            mask: 'position:fixed;top:0;left:0;width:100%;height:100%;background:#000;opacity:.5;filter:alpha(opacity=50);z-index:9999;',
            box: 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);background:#fff;padding:20px 30px;border-radius:4px;box-shadow:0 2px 10px rgba(0,0,0,.2);z-index:10000;min-width:260px;text-align:center;',
            msg: 'font-size:14px;color:#333;line-height:1.5;margin-bottom:18px;word-break:break-all;',
            btn: 'padding:6px 24px;background:#1890ff;color:#fff;border:none;border-radius:3px;cursor:pointer;font-size:14px;'
        };
        mask.style.cssText = css.mask;
        alertBox.style.cssText = css.box;
        msgBox.style.cssText = css.msg;
        btn.style.cssText = css.btn;
        btn.innerHTML = '確定';

        // 4. 事件:點擊確定銷毀
        btn.onclick = function () {
            document.body.removeChild(mask);
            document.body.removeChild(alertBox);
            alertBox = mask = btn = null; // 釋放引用,下次重建
        };
    }

    function showCustomAlert(text) {
        ensureDOM();
        alertBox.querySelector('div').textContent = text; // 更新訊息
        // 重新插入(若上次已移除)
        if (!document.body.contains(mask)) {
            document.body.appendChild(mask);
            document.body.appendChild(alertBox);
        }
    }
})(window);

關鍵技術點解析

技術點說明
立即執行函數 (IIFE)形成閉包,避免污染全局變數;傳入 win 參數壓縮後更小
預編譯期覆寫var nativeAlert = win.alert; win.alert = ... 放在 IIFE 頂部,確保腳本載入瞬間生效
單例 DOM首次調用才創建,後續復用;關閉時移除 DOM 並置空引用,防記憶體洩漏
cssText 批量寫樣式IE8 不支援 el.style.transform 等屬性寫法,cssText 字串解析無此問題
transform + -ms-transform垂直水平居中,IE9+ 支援標準,IE9 需前綴
filter:alpha(opacity=50)IE8 透明度兼容

進階擴展:支援回調、標題、多按鈕

win.alert = function (msg, options) {
    options = options || {};
    showCustomAlert({
        title: options.title || '提示',
        message: msg,
        onConfirm: options.onConfirm || function () {},
        confirmText: options.confirmText || '確定',
        cancelText: options.cancelText, // 若提供則顯示取消按鈕
        onCancel: options.onCancel
    });
};

內部 showCustomAlert 根據配置動態渲染按鈕區,onConfirm/onCancel 執行後銷毀彈窗。

常見坑點與解決

  • 覆寫前已調用 alert:將腳本放在 <head> 最早載入,或用 defer 確保 DOMContentLoaded 前執行。
  • 多次快速調用疊加:單例模式 + 關閉時移除 DOM,確保同一時刻僅一個彈窗。
  • iframe 跨域調用:需在父頁面暴露 window.showCustomAlert,子頁面調用 parent.showCustomAlert()。
  • 移動端鍵盤遮擋:彈窗 top: 50%; transform: translateY(-50%) 並在 focus 時 scrollIntoView。

總結

「造假」替換原生 alert 是前端工程化常見技巧:**不修改不可變的原生實現,而是在上層攔截並提供可控替代品**。同理可實現自定義 confirm、prompt、onbeforeunload 等,統一專案 UI 風格並擴展業務能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved