小試 SweetAlert2 快顯通知模式
| | 2 | | ![]() |
前陣子找到 JavaScript 快顯通知套件 - NOTY,雖然原作者已不再維護,但評估它最符合我的需求,如要修改也在我的能力範圍,維持原判。但接二連三有讀者提到,老朋友 SweetAlert2 其實就有定時自動關閉及其他快顯通知所需功能,有「眾裡尋他千百度,驀然回首,那人卻在燈火闌珊處」的驚喜感,不試用看看好像說不過去。
經過研究,結論是 SweetAlert2 的確能實現類似 NOTY 的通知效果,但未必能取代,看應用情境需求。
SweetAlert2 有個 Toasts 範例,訊息可顯示於右上角倒數後自動隱藏,也提供關閉鈕,呈現效果如同一般快顯通知;若要像 NOTY 滑鼠移在訊息上停止倒數,可透過 didOpen 事件為訊息元素加 mouseenter、mouseleave 事件可實現。快顯模式的訊息也能加上確認、取消鈕,但它不會遮蔽網頁,若想強迫使用者按鈕後再繼續得自己加上遮罩,幸好之前上過單兵基本教練,這回再次派上用場。
花了點時間,我試著用 SweetAlert2 做出與 NOTY 幾乎相同的效果:
感覺不賴吧?程式範例如下:線上展示
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@4.0.0/animate.min.css" />
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
</style>
</head>
<body>
<button onclick="testToast()">Toast</button>
<button onclick="testConfirm()">Confirm</button>
<pre id="log"></pre>
<script>
const Toast = Swal.mixin({
toast: true,
position: 'top-right',
showConfirmButton: false,
showClass: {
popup: 'animate__animated animate__fadeInRight'
},
hideClass: {
popup: 'animate__animated animate__fadeOutRight'
},
timer: 2500,
timerProgressBar: true,
didOpen: toast => {
toast.addEventListener('mouseenter', Swal.stopTimer);
toast.addEventListener('mouseleave', Swal.resumeTimer);
},
showCloseButton: true
});
let i = 1;
function testToast() {
Toast.fire({
icon: 'success', title: `資料更新完成${i++}`
});
}
const logger = document.getElementById('log');
function testConfirm() {
Toast.fire({
icon: 'question', title: '您確定要按下確定?',
timer: false, showCloseButton: false,
confirmButtonText: '確定', cancelButtonText: '取消',
showConfirmButton: true, showCancelButton: true,
buttonsStyling: false,
didOpen: toast => {
const mask = document.createElement('div');
mask.setAttribute('id', 'swal2_toast_overlay');
mask.style = `position:absolute;top:0;left:0;width:100%;height:100%;z-index:1050;background-color:#444;opacity:0.5`;
document.body.appendChild(mask);
},
willClose: toast => {
const mask = document.getElementById('swal2_toast_overlay');
if (mask) mask.remove();
return true;
}
})
.then((res) => logger.insertAdjacentText('beforeend',
`已按下${res.value ? '確定' : '取消'}\n`));
}
</script>
</body>
</html>
接著來說說,SweetAlert2 不能取代 NOTY 的原因:它每次只能顯示一個對話框。小改程式,來看問題出在哪裡:
let i = 1;
function testToast() {
Toast.fire({
icon: 'success', title: `資料更新完成${i++}`
});
}
由於 SweetAlert2 是以 alert() 的概念出發,同一時間只會存在一個對話框,若連續觸發,訊息來不及顯示就被後面的訊息蓋掉。初步看了 Swal 程式碼及參考網路討論:
我認為這是 alert 本質及設計理念的限制,要魔改到一次顯示多訊息不是不可能,但這像人在豆漿燒餅店,堅持要吃白酒蛤蜊義大利麵,何苦來哉?
結論,如果你的快顯通知不存在一次多筆的應用需求,用 SweetAlert2 可一次滿足標準提示對話框及快顯通知兩種呈現方式,也是不錯的選擇。
Study of toast display mode of SweetAlert2 library.
Comments
# by Cash
人在豆漿燒餅店,堅持要吃白酒蛤蜊義大利麵 <== 這句話打到我了 XD
# by Tim
Alertify 也很不錯用喔