前言
最近開發的Google Material Style網站(範例:https://agmstudio.io/themes/material-style/2.3.1/component-snackbar.html)
引用到的JS Notification套件:SnackBar,發現除了配色外,其餘長得很像Google網站的Notification ↓
此套件容易上手、寫的程式碼也少 ※相比之下,w3schools教你從頭寫到尾的教學就有點複雜:How TO - Snackbar / Toast
但官網文件隱藏很多沒公開的知識,所以寫此篇文章整理一下我發現的祕技XD
實作
進入官網:https://www.polonel.com/snackbar/
點擊Download下載壓縮包並解壓縮
接著到SnackBar-master\dist目錄下把snackbar.css、snackbar.js兩個檔案放置到自己Web專案內引用到網頁上即可
基本使用方法在<script>區段內寫下↓
Snackbar.show({ text: '範例文字' });
完整Html程式碼↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My Demo SnackBar</title>
<!--引用snackbar.css-->
<link href="dist/snackbar.css" rel="stylesheet" />
</head>
<body>
<!--引用snackbar.js-->
<script src="dist/snackbar.js"></script>
<script type="text/javascript">
window.onload = function () {
//基本用法↓
Snackbar.show({ text: '範例文字' });
}
</script>
</body>
</html>
基本執行效果↓,Notification會出現在網頁的左下角
官網文件沒告訴你的事(祕技?)
祕技1:此套件不相依於jQuery
也就是說Web專案有使用到jQuery的話,jQuery不管怎麼改版都不會影響到此套件的使用。
這件事我自己完整survey過它的snackbar.js原始碼才知道
GitHub連結:https://github.com/polonel/SnackBar
可以留意當在呼叫Snackbar.show()時,它不使用jQuery的$.extend()來merge預設參數,而是另外寫一個仿$.extend()的原生JS function來merge使用者傳入的參數
※多學到一種Pure JS Extend寫法XD:http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
祕技2:官網文件的Default參數有誤
以下是官網的12個參數說明,很簡單明瞭,就不再用中文重新詮釋,不過留意以下劃紅線的三個參數
該三個參數,Default值正確如下↓
祕技3:其實還有四個參數可以控制顯示第二顆按鈕
看到上述的原始碼可以發現,其實還有showSecondButton、secondButtonText、secondButtonTextColor、onSecondButtonClick這幾個參數可以使用
雖然官網文件沒說明,但從參數名稱來看,應該也推測得出來是什麼用途,完整Html範例如下↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My Demo SnackBar</title>
<!--引用snackbar.css-->
<link href="dist/snackbar.css" rel="stylesheet" />
</head>
<body>
<!--引用snackbar.js-->
<script src="dist/snackbar.js"></script>
<script type="text/javascript">
window.onload = function () {
Snackbar.show({
text: '儲存至「資料庫」',
//第二顆按鈕用法↓
showSecondButton: true, secondButtonText: "查看奇摩", secondButtonTextColor: "#64b5f6", onSecondButtonClick: function (element)
{
window.location.href = "http://tw.yahoo.com";
}
});
}
</script>
</body>
</html>
執行結果↓
我想隱藏的四個參數(第二顆按鈕)是想要完全仿效Google的UI吧XD
但是Google本家的關閉Notification按鈕是「✖」 、「✕」(我使用嘸蝦米輸入法,叉叉還能打出來)
要把預設的綠色DISMISS字串改掉的話,得修改兩個參數:actionText、actionTextColor ↓
Snackbar.show({
text: '儲存至「資料庫」',
//改這兩行
actionText: "✕",//叉叉字串
actionTextColor: '#fff', //白色
//第二顆按鈕用法↓
showSecondButton: true, secondButtonText: "查看奇摩", secondButtonTextColor: "#64b5f6",
onSecondButtonClick: function (element) {
window.location.href = "http://tw.yahoo.com";
}
});
或進階一點使用fontawesome 5的圖示,完整Html代碼如下↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My Demo SnackBar</title>
<!--引用snackbar.css-->
<link href="dist/snackbar.css" rel="stylesheet" />
</head>
<body>
<!--引用fontawesome icon-->
<script defer src="https://use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script>
<!--引用snackbar.js-->
<script src="dist/snackbar.js"></script>
<script type="text/javascript">
window.onload = function () {
Snackbar.show({
text: '儲存至「資料庫」',
//改這兩行
actionText: "<i class='fas fa-times'></i>",//fontawesome icon
actionTextColor: '#fff', //白色
//第二顆按鈕用法↓
showSecondButton: true, secondButtonText: "查看奇摩", secondButtonTextColor: "#64b5f6",
onSecondButtonClick: function (element) {
window.location.href = "http://tw.yahoo.com";
}
});
}
</script>
</body>
</html>
另外補充:Google本家的Notification位置在網頁的正下方,而且關閉動作的Notification是往下滑出去(但此套件點擊關閉按鈕會直接淡出)
所以要幾乎仿效Google Style Notification的話,程式碼如下
Snackbar.show({
text: '儲存至「資料庫」',
pos: 'bottom-center',//出現位置為畫面正下方
actionText: "✕", //關閉按鈕文字
actionTextColor: '#fff', //白色
onActionClick: function (element) {//當點擊關閉按鈕時
//element為<div class="snackbar-container"></div>
let sty = element.style;
//由於snackbar.css有定義.snackbar-container的transition,所以下面兩行會有轉場動畫效果
sty.bottom = "-100px"; //往下滑動
sty.opacity = 0;//淡出消失
},
//第二顆按鈕用法↓
showSecondButton: true, secondButtonText: "查看奇摩", secondButtonTextColor: "#64b5f6",
onSecondButtonClick: function (element) {
window.location.href = "http://tw.yahoo.com";
}
});
執行結果↓
程式碼寫到此,應該已經發覺要傳遞的參數實在太多,這邊提供一種自訂預設值的寫法
先新增一個.js檔命名為MysnackbarSetting.js,裡面的程式碼放置最常使用到的參數↓
//宣告一個物件
let MysnackbarOption = {
actionText: "✕", //關閉按鈕文字
actionTextColor: '#fff', //關閉按鈕顏色 白色
pos: 'bottom-center',//出現位置為畫面正下方
onActionClick: function (element) {//當點擊關閉按鈕時
//element為<div class="snackbar-container"></div>
let sty = element.style;
//由於snackbar.css有定義.snackbar-container的transition,所以下面兩行會有轉場動畫效果
sty.bottom = "-100px"; //往下滑動
sty.opacity = 0;//淡出消失
}
};
接著網頁引用該MysnackbarSetting.js,完整Html代碼如下↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My Demo SnackBar</title>
<!--引用snackbar.css-->
<link href="dist/snackbar.css" rel="stylesheet" />
</head>
<body>
<!--引用jQuery-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<!--引用snackbar.js-->
<script src="dist/snackbar.js"></script>
<!--引用最常使用到的參數-->
<script src="dist/MysnackbarSetting.js"></script>
<script type="text/javascript">
window.onload = function () {
Snackbar.show($.extend(true,MysnackbarOption,
{ //寫下此頁面才會使用到的參數
text: "已儲存至資料庫"
})
);//end show
}
</script>
</body>
</html>
執行結果↓
祕技4:執行Snackbar.close() 可以手動關閉Notification
不過該留意的是,預設它會以淡出行為去關閉Notification,請見原始碼↓
如果在執行Snackbar.close()時,想要關閉行為是往下滑出去的話,可以在剛剛的MysnackbarSetting.js檔裡寫下↓
//宣告一個物件
let MysnackbarOption = {
actionText: "✕", //關閉按鈕文字
actionTextColor: '#fff', //關閉按鈕顏色 白色
pos: 'bottom-center',//出現位置為畫面正下方
onActionClick: MySnackbarClose//當點擊關閉按鈕時
};
function MySnackbarClose()
{
if (Snackbar.current)//防呆
{
//Snackbar.current 為 <div class="snackbar-container"></div>
let sty = Snackbar.current.style;
//由於snackbar.css有定義.snackbar-container的transition,所以下面兩行會有轉場動畫效果
sty.bottom = "-100px"; //往下滑動
sty.opacity = 0;//淡出消失
}
}
//改寫close function
Snackbar.close = MySnackbarClose;
完整Html的使用範例↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>My Demo SnackBar</title>
<!--引用snackbar.css-->
<link href="dist/snackbar.css" rel="stylesheet" />
</head>
<body>
<button id="btn">button</button>
<!--引用jQuery-->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<!--引用snackbar.js-->
<script src="dist/snackbar.js"></script>
<!--引用自訂參數-->
<script src="dist/MysnackbarSetting.js"></script>
<script type="text/javascript">
$(function () {
Snackbar.show($.extend(true, MysnackbarOption,
{ //寫下此頁面才會使用到的參數
text: "已儲存至資料庫"
})
);//end show
//當click畫面上的button
$("#btn").click(function () {
//手動執行關閉
Snackbar.close();
});//end click
});
</script>
</body>
</html>
其它補充
Snackbar此套件一次只會出現一個Notification就如同Google網站一樣(其它Notification套件有些會重複出現)
當第二個Notification出現時,前一個Notification就會被移除掉
也就是說,你不會看到以下情況↓
如果有傳遞customClass參數
留意自訂的ClassName出現的位置在最外層的容器 <div class="snackbar-container"></div>
有個地方可能會被原始碼檢測誤判Client DOM Code Injection漏洞
僅管Notification呈現的文字都是程式設計師自己給的,並非抓前端user給的value
但還是有可能會被原始碼檢測誤判漏洞
問題出在以下的.innerHTML和.text這兩個關鍵字
解法方案把$default參數的text改成content或其它名稱
撰寫本文時,此套件為v0.1.10版
未來官網文件、snackbak.js應該會陸續改版,改掉上述我提到的問題
如果未來我還記得此套件的話,到時候再修正此篇文章吧XD
本文的Live Demo
補充
上網使用關鍵字尋找「SnackBar」時,得留意Material Design for Bootstrap的作者fezvrasta也有另外寫一個SnackbarJS套件,兩者特性有點不太一樣,要小心別搞混XD