Notification
是HTML5新增的API,用于向用户配置和显示桌面通知。上次在别的网站上看到别人的通知弹窗,好奇之余也想知道如何实现的。实际去查一下发现并不复杂,且能够说比较简单,故写篇博客分享给你们,但愿能帮大家了解这个API。html
我还发了一个npm包:notification-Koro1,很是轻量简洁,以为不错的话,点个Star吧~前端
Notification
的表现:
Notification
特性该通知是脱离浏览器的,即便用户没有停留在当前标签页,甚至最小化了浏览器,也会在主屏幕的右上角显示通知,而后在一段时间后消失。html5
咱们能够监听通知的显示,点击,关闭等事件,好比点击通知打开一个页面。git
API的具体细节,等下再说,先试试这个API~web
下面是一个简单的栗子,你们能够先在各个网站的控制台里面运行查看Notification
的效果:chrome
var options = { dir: "auto", // 文字方向 body: "通知:OBKoro1评论了你的朋友圈", // 通知主体 requireInteraction: true, // 不自动关闭通知 // 通知图标 icon: "https://upload-images.jianshu.io/upload_images/5245297-818e624b75271127.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" }; notifyMe('这是通知的标题', options); function notifyMe(title, options) { // 先检查浏览器是否支持 if (!window.Notification) { console.log('浏览器不支持通知'); } else { // 检查用户曾经是否赞成接受通知 if (Notification.permission === 'granted') { var notification = new Notification(title, options); // 显示通知 } else if (Notification.permission === 'default') { // 用户还未选择,能够询问用户是否赞成发送通知 Notification.requestPermission().then(permission => { if (permission === 'granted') { console.log('用户赞成受权'); var notification = new Notification(title, options); // 显示通知 } else if (permission === 'default') { console.warn('用户关闭受权 未刷新页面以前 能够再次请求受权'); } else { // denied console.log('用户拒绝受权 不能显示通知'); } }); } else { // denied 用户拒绝 console.log('用户曾经拒绝显示通知'); } } } 复制代码
MDN:目前Notification
除了IE浏览器不支持外, 其余浏览器都已支持桌面通知,移动端浏览器基本都未支持。npm
由于兼容性问题,因此在使用Notification
以前,咱们须要查看浏览器是否支持Notification
这个API:promise
if(window.Notification){ // 桌面通知的逻辑 } 复制代码
为了不网站滥用通知扰民,在向用户显示通知以前,须要通过用户赞成。浏览器
Notification.permission
用于代表当前通知显示的受权状态,它有三个值:
default
: 默认值,用户还未选择granted
: 用户容许该网站发送通知denied
: 用户拒绝该网站发送通知检测浏览器是否支持Notification
以后,须要检测一下用户通知权限。
if (Notification.permission === 'granted') { console.log('用户曾经赞成受权'); // 随时能够显示通知 } else if (Notification.permission === 'default') { console.log('用户还未选择赞成/拒绝'); // 下一步请求用户受权 } else { console.log('用户曾经拒绝受权 不能显示通知'); } 复制代码
当Notification.permission
为default
的时候,咱们须要使用Notification.requestPermission()
来请求用户权限。
Notification.requestPermission()
基于promise语法,then的回调函数参数是用户权限的状态Notification.permission
的值。
Notification.requestPermission().then(permission => { if (permission === 'granted') { console.log('用户赞成受权'); // 随时能够显示通知 } else if (permission === 'default') { console.log('用户关闭受权 能够再次请求受权'); } else { console.log('用户拒绝受权 不能显示通知'); } }); // 老版本使用的是回调函数机制:Notification.requestPermission(callback); 参数同样 复制代码
当Notification.permission
为granted
时,请求到用户权限以后,没必要当即发送通知,能够在任意时刻,以任意形式来发送通知。
const options = {}; // 传空配置 const title = '这里是标题'; const notification = new Notification(title, options) // 显示通知 复制代码
上面这段代码就能够显示一个简单的通知了,只要用户容许你弹窗。
Notification
的参数:requireInteraction: 保持通知不自动关闭
默认值为false,通知会在三四秒以后自动关闭。
当设置为true
,而且当有超过两个通知(new Notification(title, options)
)时,会出现以下图的通知叠加状态。
这种状况显然,咱们只能默认操做最后一个通知,除非你把每一个通知返回的实例都保存下来。
我发布的npm包:notification-koro1,能够自定义必定的时间间隔自动关闭不自动关闭的通知,也能够一次性关闭全部通知
PS:若是没有触发叠加,极可能是由于你两次通知的tag配置项是相同的(相同tag只能出现一个弹窗)。
PS: safari下不支持该选项,默认自动关闭
renotify:相同
默认值为false,chorme下相同tag的通知不替换,仍是老的通知
设置为true
, 两个相同tag的通知,新通知替换以前旧的通知。
注意:使用renotify
,必需要同时设置tag
选项,不然将会报错。
PS: safari下不支持该选项,默认两个相同tag的通知,新通知替换以前旧的通知。
Notification
的实例:生成通知,会返回一个实例,以下:
const instanceNotification = new Notification(title, options) 复制代码
instanceNotification
就是当前通知的实例,在该实例上,咱们能够查询该通知的配置,监听事件,调用实例方法。
下文都以instanceNotification
指代通知返回的实例。
在通知实例上能够读取到设置通知时的全部配置,好比:
通知标题:instanceNotification. title
、通知内容:instanceNotification. body
、通知图标:instanceNotification. icon
等。
PS: 这些属性都是只读的,不能删除,不能修改,不能遍历。
咱们可使用通知的实例来监听通知的事件:
click
: 用户点击通知时被触发show
: 通知显示的时候被触发error
: 通知遇到错误时被触发close
: 用户关闭通知时被触发instanceNotification.onclick = e => { // do something 能够是:打开网址,发请求,关闭通知等 } 复制代码
注意:最好是一发出通知就当即监听事件,不然有些事件可能一开始没被触发或永远不会触发。
例如:用定时器5秒后才监听通知的点击和显示事件,则永远不会触发通知显示的回调,点击事件在5秒后才能够正常起做用但会错误五秒以前用户的点击。
instanceNotification.close()
复制代码
没有设置不自动关闭的话,chrome通知将会在4.5秒左右自动关闭通知,safari则是5秒钟(没法设置不自动关闭)。
notification没有定时控制通知多久后消失的功能,当出现多个通知,也没法统一关闭。
这两个问题,在我发布的NPM包:notification-koro1中,都解决掉了,并提供更清晰的回调
这里是一些API/浏览器细节,以及可能会遇到的问题,能够先不看,等真正遇到了,回头再来看。
一旦用户禁止网站显示通知,网站就不能再请求用户受权显示通知,须要用户去设置中更改。
chrome浏览器的通知设置位置:设置>高级>内容设置>通知
saafari浏览器:偏好设置>网站>通知>找到网站>修改权限/恢复默认
在chorme浏览器中:当用户关闭请求权限的弹窗(右上角的叉叉),页面还没刷新,咱们能够再次向用户请求权限。页面刷新事后,浏览器默认用户拒绝。
在safari浏览器下,没有关闭请求权限的选项,用户必须选择赞成/拒绝。
多是网站进行了同源限制(好比github),不是域名下面的图片,会报错,不能调用。
tag
相同的通知,同时只能出现一个,老通知是否会被覆盖取决于:renotify
配置和浏览器。在safari下面,同一个网站(好比谷歌),一样的代码,chorme能够正常显示icon,safari却没有icon,也没有报错。
谷歌以后发现,在stack overflow里面看到safari只支持body和tag选项,并不支持icon选项。
在safari和chrome下短期内连续触发通知(不设tag
,不设requireInteraction
),会出现以下表现:
这个表现,通知没有icon、标题、内容,就显得没有意义了,浏览器以这种形式,限制开发者不要频繁打扰用户。
试一下notification-Koro1啦, 持续维护,简单方便~
本文写的比较细,能够先mark一下,而后之后真正用到这个API了,能够先经过文中的栗子,而后再查找对应的内容。
还有就是注意浏览器间的差别,我本身就试了chrome和safari,而后这两个浏览器在实现细节上有不少不同的地方,开发的时候注意一下。
以上2019.02.17
参考资料: