天天看點

【浏覽器】854- 淺談浏覽器通知 Notification

前言

前段時間接到一個需求,我們的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就可以恢複正常。

效果如圖

【浏覽器】854- 淺談浏覽器通知 Notification

修改title是相容性比較好,實作比較簡單的一種方式,但是用最小化浏覽器效果就很不好了,為了解決這個問題。html5推出notification api

方法二:web notification

我們先來看一下效果

【浏覽器】854- 淺談浏覽器通知 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();
   });
 }      

如果沒有彈出彈窗,有兩種可能

  1. 浏覽器不支援Notification API
  2. 需要獲得通知授權。

是否支援Notification可以通過window.Notification是否存在來判斷,如果支援的情況下沒有彈出就需要獲得授權。通過調用Notification.requestPermission(callback)來擷取使用者授權,授權後可正常彈出。

【浏覽器】854- 淺談浏覽器通知 Notification

也可以點選圖中的小鎖圖示,允許通知。

不同浏覽器的實作樣式略有不同,js代碼不能控制具體的位置和樣式,可以确定标題,内容,和一個系統icon。對于chrome浏覽器,一般幾秒鐘後會被自動關閉,其他浏覽的各個版本實作各有不同,如我用的360極速,

長時間也不會關閉, 可以看到已經顯示了12分鐘。

【浏覽器】854- 淺談浏覽器通知 Notification

chrome浏覽器效果實作

【浏覽器】854- 淺談浏覽器通知 Notification

可以通過調用Notification.close()方法,主動關閉關閉通知。

new Notification(title, options)

通過new構造,調用通知方法。其中title是必填參數,表示通知的标題内容,options是可選參數,詳見下表:

屬性 含義 類型
body 内容主體 字元串
icon 通知圖示 字元串
silent 是否需要聲音 布爾值
sound 聲音位址,可以播放提示聲音 字元串
data 任意類型和通知相關聯的資料 對象
vibrate 震動模式 數組
tag 通知辨別 字元串
renotify 通知是否使用疊加效果,預設true,fasle則為替換 布爾值
noscreen 是否不在螢幕上顯示通知,用于移動端,預設false 布爾值

通知堆疊效果 false僅顯示最新的一個

【浏覽器】854- 淺談浏覽器通知 Notification

其中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的相容性

【浏覽器】854- 淺談浏覽器通知 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 用來配置角标數字, 如下圖

【浏覽器】854- 淺談浏覽器通知 Notification

notify.notify() 直接發起提示

具體使用可以參看 https://github.com/cywcd/iNotify, 非常詳細。

總結

H5的Notification為浏覽器通知提供了一個很好的解決方案,使用者體驗優秀,結合自定義聲音,能帶來不錯的體驗,但是目前的相容性一般,即便是使用iNotify.js,是以在生産環境中使用需要注意使用場景。在移動端的實作會更不穩定一些,建議多多測試,做好保底方案。