前言
前段時間接到一個需求,我們的web系統有電話接聽功能。産品希望有電話呼入的時候,能夠有效提示使用者,無論使用者是否在目前的系統頁簽上,甚至浏覽器被最小化以後也能提醒使用者。就着這個需求,我做了一些探索。
前端對使用者的通知一般局限于頁面之内,比如alert,confirm。或者js控制一個彈窗提醒使用者。有些場景需要在頁面之外通知使用者,即當使用者頁簽不在本頁面,或者浏覽器已經被收起來的情況。
本文介紹一些浏覽器通知方式。
方法一:閃爍浏覽器标題
利用document.title修改頁簽的标題,使用定時器來回切換内容實作标題閃爍,引起使用者注意。
例子:
function sendNotificationFn(message, time) {
var oldTitle = document.title; // 儲存原有标題
var changeVal = 1;
var notice = setInterval(function() {
if (changeVal) {
document.title = message;
changeVal = 0
} else {
document.title = oldTitle;
changeVal = 1
}
}, time || 1000);
return notice;
}
sendNotificationFn('有新的通知', 500);
// 中止通知
clearInterval(notice);
使用上述方法就可以不斷閃爍title,引起使用者的注意。方法會傳回定時器,清除定時器重新設定title就可以恢複正常。
效果如圖
修改title是相容性比較好,實作比較簡單的一種方式,但是用最小化浏覽器效果就很不好了,為了解決這個問題。html5推出notification api
方法二:web notification
我們先來看一下效果
會在系統的右下方顯示一個通知,即便頁簽不在使用者的視窗内,也可以觸發該效果。
一個簡單的例子
function sendNotification() {
new Notification("通知标題:", {
body: '通知内容',
icon: 'https://pic1.zhuanstatic.com/zhuanzh/50b6ffe4-c7e3-4317-bc59-b2ec4931f325.png'
})
}
if (window.Notification.permission == "granted") { // 判斷是否有權限
sendNotification();
} else if (window.Notification.permission != "denied") {
window.Notification.requestPermission(function (permission) { // 沒有權限發起請求
sendNotification();
});
}
如果沒有彈出彈窗,有兩種可能
- 浏覽器不支援Notification API
- 需要獲得通知授權。
是否支援Notification可以通過window.Notification是否存在來判斷,如果支援的情況下沒有彈出就需要獲得授權。通過調用Notification.requestPermission(callback)來擷取使用者授權,授權後可正常彈出。
也可以點選圖中的小鎖圖示,允許通知。
不同浏覽器的實作樣式略有不同,js代碼不能控制具體的位置和樣式,可以确定标題,内容,和一個系統icon。對于chrome浏覽器,一般幾秒鐘後會被自動關閉,其他浏覽的各個版本實作各有不同,如我用的360極速,
長時間也不會關閉, 可以看到已經顯示了12分鐘。
chrome浏覽器效果實作
可以通過調用Notification.close()方法,主動關閉關閉通知。
new Notification(title, options)
通過new構造,調用通知方法。其中title是必填參數,表示通知的标題内容,options是可選參數,詳見下表:
屬性 | 含義 | 類型 |
body | 内容主體 | 字元串 |
icon | 通知圖示 | 字元串 |
silent | 是否需要聲音 | 布爾值 |
sound | 聲音位址,可以播放提示聲音 | 字元串 |
data | 任意類型和通知相關聯的資料 | 對象 |
vibrate | 震動模式 | 數組 |
tag | 通知辨別 | 字元串 |
renotify | 通知是否使用疊加效果,預設true,fasle則為替換 | 布爾值 |
noscreen | 是否不在螢幕上顯示通知,用于移動端,預設false | 布爾值 |
通知堆疊效果 false僅顯示最新的一個
其中vibrate是個很有意思的屬性,在Notification使用vibrate屬性可以使裝置震動,填入[300, 100, 300], 表示裝置振動
300毫秒,然後停止100毫秒,再振動300毫秒
new Notification("通知标題:", {
body: '通知内容',
vibrate: [300, 100, 300],
icon: 'https://pic1.zhuanstatic.com/zhuanzh/50b6ffe4-c7e3-4317-bc59-b2ec4931f325.png'
})
使用該效果雖然更能引起使用者的注意,但是也會有過分打擾使用者。有些浏覽器也沒有實作該效果,慎重使用。
再來看看Notification的相關事件
事件名 | 含義 |
Notification.onclick | 通知被點選時 |
Notification.onerror | 通知顯示異常時,躲在使用者沒有給通知時觸發 |
Notification.onclose | 通知被關閉時 |
Notification.onshow | 通知顯示時 |
Notification還提供了一些隻讀屬性,可供一些特殊需求使用,大部分和options相同
列如:title,body,tag,icon,silent,timestamp(通知建立的時間),noscreen等
Notification的相容性
在現代浏覽器的支援還是比較好的,edge的高版本也做了支援,不過對于IE已經其他老版本的浏覽器,還是需要考慮
相容性和備用方案。
iNotify.js 方法庫介紹
上述兩種方法使用的時候免不了要自己封裝,尤其是Notification,api和屬性都比較多,推薦使用iNotify.js來解決通知問題
iNotify.js。可以幫助實作浏覽器的 title 閃爍、滾動、聲音提示、chrome、Firefox、Safari等系統通知。
這個例子是進行聲音提示
var iNotify = new iNotify().init();
//推薦下面寫法
var iNotify = new iNotify({
message: '有消息了。',//标題
effect: 'flash', // flash | scroll 閃爍還是滾動
openurl:"http://www.bing.com", // 點選彈窗打開連接配接位址
onclick:function(){ //點選彈出的窗之行事件
console.log("---")
},
//可選播放聲音
audio:{
//可以使用數組傳多種格式的聲音檔案
file: ['msg.mp4','msg.mp3','msg.wav']
//下面也是可以的哦
//file: 'msg.mp4'
},
//标題閃爍,或者滾動速度
interval: 1000,
//可選,預設綠底白字的 Favicon
updateFavicon:{
// favicon 字型顔色
textColor: "#fff",
//背景顔色,設定背景顔色透明,将值設定為“transparent”
backgroundColor: "#2F9A00"
},
//可選chrome浏覽器通知,預設不填寫就是下面的内容
notification:{
title:"通知!",//設定标題
icon:"",//設定圖示 icon 預設為 Favicon
body:'您來了一條新消息'//設定消息内容
}
})
import Notify from '@wcjiang/notify';
const notify = new Notify({
effect: 'flash',
interval: 500,
});
notify.setFavicon('1');
notify.setTitle('New title');
notify.setInterval(200);
notify.notify({ openurl: 'http://localhost:8084/#/admin/home' });
setTitle 用來設定标題
setInterval 用來配置閃動間隔
setFavicon 用來配置角标數字, 如下圖
notify.notify() 直接發起提示
具體使用可以參看 https://github.com/cywcd/iNotify, 非常詳細。
總結
H5的Notification為浏覽器通知提供了一個很好的解決方案,使用者體驗優秀,結合自定義聲音,能帶來不錯的體驗,但是目前的相容性一般,即便是使用iNotify.js,是以在生産環境中使用需要注意使用場景。在移動端的實作會更不穩定一些,建議多多測試,做好保底方案。