嫌瀏覽器內建的 alert() / confirm() 太醜,Kendo UI 有 kendo.alert() 與 kendo.confirm() 可取代 window.alert()/confirm(),小缺點是標題列一律顯示網址難以調整,加上網頁未必就有引用 Kendo UI,為此下載龐大的 Kendo UI js 有殺雞用牛刀之嫌。

我找到一個美觀大方使用簡便,可取代 window.alert() 的程式庫 - SweetAlert2。(其實今天是我第二次用它,前次使用沒寫筆記,下場是重查一次文件。記取教訓,回家乖乖補交功課,防止下次再查第三次 Orz... 誰來救救中年人的腦子?)

引用 SweetAlert2 的方法有兩種,第一種是使用內含 css 可自動注入的 sweetalert2.all.min.js,另外也可分別載入 sweetalert2.min.js 及 sweetalert2.min.css,官方 CDN 位置在 https://www.jsdelivr.com/package/npm/sweetalert2

SweetAlert2 不依賴 jQuery,跟 jQuery、React、Angular、Vue.js 都能和平相處,個性隨和。

用 SweetAlert2 取代 alert() / confirm() 的起手式如下: (注意:IE11 需加掛 Promise Polyfill 才能相容) 線上展示

<html>
<head><meta charset="utf-8"></head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
    <!-- 若需相容 IE11,要加載 Promise Polyfill-->
    <script src="https://cdn.jsdelivr.net/npm/promise-polyfill"></script>
    <button onclick='alertTest()'>Alert</button>
    <button onclick='confirmTest()'>Confirm</button>
    <script>
        function alertTest() {
            Swal.fire(
                "查詢作業失敗", //標題 
                "您所輸入的序號不存在或是系統被玩壞了!", //訊息內容(可省略)
                "error" //圖示(可省略) success/info/warning/error/question
                //圖示範例:https://sweetalert2.github.io/#icons
            );
        }
        function confirmTest() {
            Swal.fire({
                title: "操作確認",
                text: "請點選你想按的按鈕",
                showCancelButton: true
            }).then(function(result) {
               if (result.value) {
                    Swal.fire("您按了OK");
               }
               else {
                   Swal.fire("您選擇了Cancel");
               }
            });
        }
    </script>
</body>
</html>

SweetAlert2 提供極佳擴充性,例如:

  • 支援 Footer 區塊顯示額外訊息
  • title、html 等參數可直接輸入 HTML (若確定輸入的是純文字,想加上 HtmlEncode(),可改用 titleText、text 參數)
  • 確認取消鈕的文字、樣式均可修改
  • 可自訂顯示及消失動畫
  • 顯示訊息支援圖片
  • 支援倒數自動關閉
  • 支援步驟一、步驟二、步驟三式串接
  • 可在按鈕事件觸發 AJAX 呼叫

以上在官網都有可實際操作的線上展示說明文件也十分完整,只能大推了!

補上一些使用經驗:

  • 使用 Swal.fire('...', '...') 簡單寫法時,第一個參數為 title、第二個參數為 html,都允許內嵌 HTML,但有簡單的 XSS 防護(內嵌 <script> 會被忽略)。若訊息內容包含 < > 等符號怕被當成 HTML 導致錯亂,可改寫為 Swal.fire({ titleText: '...', text: '...' })
  • 個人嫌 SweetAlert2 的顯示動畫過於花俏,通常會設定 animation: false 關掉它
  • SweetAlert2 的預設樣式字型偏大,可用以下自訂樣式調整:
    <style>
        .swal2-popup.swal2-modal {
            font-size: 10pt; 
        }
        .swal2-modal .swal2-title {
            font-size: 1.2em;
        }
        .swal2-modal button {
            padding: 3px 6px;
        }
    </style>
    
  • SweetAlert2 使用的 Promise then() 需判斷 result.value 在使用者按下 OK 時做動作。我偏好 jQuery 的 done()、fail() 寫法,習慣包裝如下:
    function swalConfirm(title, msg) {
        var dfd = jQuery.Deferred();
        Swal.fire({
            title: title,
            html: msg,
            icon: 'question',
            showCancelButton: true,
            animation: false
        }).then(function (result) {
            if (result.value) dfd.resolve();
            else dfd.reject();
        });
        return dfd.promise();
    }
    
    function confirmTest() {
        swalConfirm("操作確認", "請點選你想按的按鈕")
            .done(function () {
                Swal.fire("您按了OK");
            })
            .fail(function () {
                Swal.fire("您選擇了Cancel");
            });
    }
    

Introducing the excellent alternative to browser's built-in window.alert()/confirm() - SweetAlert2.


Comments

# by markchu

animation: false 有說要改成用 showClass 跟 hideClass取代。

# by ByTIM

看起來比公司的還棒,等等跟主管說一下好了!感謝分享。

# by Joinlu

請問內容如何做斷行?

# by Jeffrey

to Joinlu,訊息文字用 HTML 格式加 <br />。

# by Huang

感覺非常好用,現行的陽春到自己不願改進...XD

# by 888

888

# by Tim

黑大您好 不知您有沒有遇過,在IE11, 加掛了polyfill後,出現module 未經定義, F12查看停在這行 module.exports = Promise; 掛入方式如下 @section scripts { @Scripts.Render("~/bundles/jqueryui") @Scripts.Render("~/bundles/toastr") @Scripts.Render("~/bundles/SweetAlert2") <script src="https://cdn.jsdelivr.net/npm/promise-polyfill"></script> }

# by Jeffrey

to Tim, 依我的理解,你引用的 npm 版本需要編譯才能執行,瀏覽器要引用應找 CDN 版本,依 https://www.npmjs.com/package/promise-polyfill 文件,要用這個 CDN Polyfill Use This will set a global Promise object if the browser doesn't already have window.Promise. https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js

# by Tim

To 黑大 非常感謝您的回覆, 不好意思問了很基本的問題, 因對npm不熟 剛才引用CDN版本, 已可成功執行 再次感謝

# by de

想請問黑大resolve()的作用是甚麼

Post a comment