浅尝浏览器桌面通知 Notification
参考:
一、前言
最近业务开发中,有一个需求,需要弹出桌面通知弹窗。
这是我从没做过的,所以开贴与大家分享一下,另外讲一下存在的问题。
二、Notification
2.1 通知实例
new Notification(title)
new Notification(title, options)
- title:标题
- options:配置(可选)
2.2 通知的配置
也是弹窗的组成部分:
- image 通知弹窗的上方大图
- icon 图标
- requireInteraction 下方的关闭按钮(默认值为 false)
- silent 通知声音静音(默认值为 false)
- body 通知内容
等等。
const options = {
image: 'https://images.unsplash.com/photo-1623653387945-2fd25214f8fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80',
// body 正文部分最多显示 4 行
body: `here the body (the first line)\nthe second line\nthe third line\nthe fourth line\nthe fifth line which cannot display\n`,
icon: 'https://images.unsplash.com/photo-1619380897562-725c909c68db?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80',
// Indicates that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.
requireInteraction: true,
silent: true
}
注意:
- body 内容最多能显示 4 行。
- image, icon 本地和远程的 url 都支持。
- requireInteraction 默认为 false,会自动关闭通知。只有设置为 true 后,面板下方才能出现“关闭”按钮,此时监听通知的关闭事件才有效果;另外,设置为 true 后,这类弹窗无法自动关闭。
- silent 默认为 false,设置为 true 后,就不会有系统提示音了,这个可以不用去系统里设置谷歌浏览器的通知声音,用这个属性就能解决。
三、可运行的代码
原功能比这个更加复杂,这里做了简化。
<!DOCTYPE html>
<html>
<head>
<title>浏览器通知</title>
</head>
<body>
<button onclick="notifyMe()">Notify me!</button>
<button onclick="mutiplyNotify()">Notify me! (mutiplyNotify)</button>
<script>
function generateNotification (title, options) {
return new Notification(title, options)
}
function mutiplyNotify () {
for (let i = 0; i < 3; i++) {
notifyMe(i)
}
}
function notifyMe(title = '') {
console.log(title)
let notification = null
const options = {
image: 'https://images.unsplash.com/photo-1623653387945-2fd25214f8fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80',
// image: './bg.jpg',
// body 正文部分最多显示 4 行
body: `here the body (the first line)\nthe second line\nthe third line\nthe fourth line\nthe fifth line which cannot display\n`,
icon: 'https://images.unsplash.com/photo-1619380897562-725c909c68db?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80',
// icon: './th.jpg',
// Indicates that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.
requireInteraction: true,
silent: true
}
// Let's check if the browser supports notifications
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
}
// Let's check whether notification permissions have already been granted
else if (Notification.permission === "granted") {
// If it's okay let's create a notification
notification = generateNotification(`Hi there! I'm a title${title}.`, options);
}
// Otherwise, we need to ask the user for permission
else if (Notification.permission !== "denied") {
Notification.requestPermission().then(function (permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
notification = generateNotification(`Hi there! I'm a title${title}.`, options);
}
});
}
// At last, if the user has denied notifications, and you
// want to be respectful there is no need to bother them anymore.
// when show
notification.onshow = function () {
console.log('when show')
}
// when click
notification.onclick = function () {
console.log('when click')
window.open(window.location.href)
}
// when close
notification.onclose = function () {
console.log('when close')
}
// when error
notification.onerror = function () {
console.log('when error')
}
}
</script>
</body>
</html>
四、总结与风险点评估
Notification 将浏览器 API 与 windows 通知功能结合,作为通知用户的一种方式显得非常巧妙,仅仅是通知也比较合适。但过度的定制化,开发性价比是不高的,存在一些问题尚未解决或难以解决。
-
一次只能在右下角显示一个,无法叠加显示多个通知面板。
-
通过点击通知面板右上角的“x”图标关闭弹窗时,无法监听到点击事件、也无法监听到关闭事件。
-
for循环依次新建通知面板时,通知面板的弹出顺序是乱序的,可能是因为线程不同导致的。
-
当用户将浏览器窗口最小化,想要实现点击通知回到原网页,似乎难以解决。
但这里提供一个取巧的方案(developer.mozilla.org/zh-CN/docs/…),利用 window.open() 打开一个新标签页(newTab),然后立即再通过 window.close() 去关闭 newTab,让用户好像就回到了原网页一样。
notification.onclick = function () { console.log('when click') window.open(window.location.href) const newTab = window.open(window.location.href) window.close('newTab') }
-
浏览器兼容性可能不太好
-
为了确保安全,这个API只允许在 HTTPS 环境下使用,但是也可以通过特别的方式去设置,这里不赘述。
添加我的微信:enjoy_Mr_cat,共同成长,卷卷群里等你 🤪。