桌面弹窗
利用 Notifications API 接口实现浏览器桌面通知。即使浏览器最小化,不停留在页面内也能弹窗通知。
构造方法:
1
| let notification = new Notification(title, options)
|
参数:
title
标题;
options
设置属性对象(常见几个属性):
body
: 通知内容。
silent
: 是否静音(如使用自定义通知铃声,可静音掉浏览器本身通知声)。
requireInteraction
: 是否自动关闭。
tag
: 通知 ID,相同 ID 通知会被替换,避免同类通知显示多个,影响用户体验。
icon
: 通知图标,图片 URL。
注意事项:桌面弹窗通知需要先调用 Notification.requestPermission()
请求用户弹窗通知权限,而且电脑浏览器通知设置也可能影响通知效果。详细用法参考下方应用实例。
标签闪烁提醒
利用定时器更换标签页标题实现闪烁提醒,通过 document.hidden
判断是否不在当前标签页。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const defaultTitle = document.title const timer = setInterval(function () { const title = document.title if (document.hidden) { if (title !== '【你有新消息】') { document.title = '【你有新消息】' } else { document.title = defaultTitle } } else { clearInterval(timer) document.title = defaultTitle } }, 500)
|
声音通知
利用 audio
HTML 音频标签,js 控制播放音频实现声音通知。
设置隐藏音频标签:
1 2 3 4 5 6 7
| <audio id="notificationAudio" style="visibility: hidden;position: absolute;bottom: 0;" controls="controls" hidden="true" src="../../assets/notice.wav" ></audio>
|
JS 控制播放:
1 2 3
| const audio = document.querySelector('#notificationAudio') audio.currentTime = 0 audio.play()
|
应用实例
在 Vue 中的后台管理系统应用实例,实现弹窗通知、声音通知、标签闪烁提醒:
注意:
下例中获取弹窗权限在页面创建就直接请求,避免用户离开页面时收到通知无法弹窗。
由于这个是后台管理系统中每个用户都需要通知,可这样使用,如果是 2C 产品,一进入页面就弹授权,可能会影响用户体验。可根据实际业务进行调整,比如用户设置中添加通知设置按钮、操作订阅时等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| <template> <audio ref="notificationAudio" style="visibility: hidden;position: absolute;bottom: 0;" controls="controls" hidden="true" src="../../assets/notice.wav" ></audio> </template>
<script> export default { name: 'Index', created() { Notification.requestPermission() }, methods: {
handleMsg() {
this.handleNotification() this.handleNotificationTag() this.handleNotificationAudio() },
handleNotification() { const options = { body: '您有新的未读消息,请及时处理', silent: true, requireInteraction: true, tag: 'Vincent Notification', icon: 'https://vincef0ng.cn/img/favicon.ico' }
if (Notification.permission === 'granted') { var notification = new Notification('消息通知', options) } else if (Notification.permission !== 'denied') { Notification.requestPermission().then(function (permission) { if (permission === 'granted') { var notification = new Notification('消息通知', options) } }) } else { }
notification.onclick = () => { window.focus() notification.close()
} },
handleNotificationTag() { const defaultTitle = document.title const timer = setInterval(function () { const title = document.title if (document.hidden) { if (title !== '【你有新消息】') { document.title = '【你有新消息】' } else { document.title = defaultTitle } } else { clearInterval(timer) document.title = defaultTitle } }, 500) },
handleNotificationAudio() { this.$refs.audio.currentTime = 0 this.$refs.audio.play() } } } </script>
|