闽公网安备 35020302035485号
3.用户不会一直将页面展示在最前面,所以需要做到页面即使被遮挡、收起,用户也能收到提示,达到及时提示的目的
2.寻找一种方式来发出通知
2.从BOM API上想办法
function notifyMe() {
if (!("Notification" in window)) {
// 检查浏览器是否支持通知
alert("当前浏览器不支持桌面通知");
} else if (Notification.permission === "granted") {
// 检查是否已授予通知权限;如果是的话,创建一个通知
const notification = new Notification("你好!");
// …
} else if (Notification.permission !== "denied") {
// 我们需要征求用户的许可
Notification.requestPermission().then((permission) => {
// 如果用户接受,我们就创建一个通知
if (permission === "granted") {
const notification = new Notification("你好!");
// …
}
});
}
// 堆代码 duidaima.com
// 最后,如果用户拒绝了通知,并且你想尊重用户的选择,则无需再打扰他们
}
这个例子中涉及三个东西:new Notification("你好!"),发出通知的简易代码。
new Notification(title) new Notification(title, options)title(必填),通知的标题,显示在通知窗口的顶部
| 属性 | 说明 |
|---|---|
| body | 一个表示通知正文的字符串,显示在标题下方,默认值是一个空字符串 |
| icon | 一个包含要在通知中显示的图标的 URL 的字符串 |
| image | 一个包含要在通知中显示的图像的 URL 的字符串 |
| requireInteraction | 指示通知应保持活动状态,直到用户单击或关闭它,而不是自动关闭。默认值为 false |
| ... | ... |
new Notification('这是标题', {
body: '这是正文',
icon: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
requireInteraction: true,
image:
'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png',
})

const notif = new Notification('这是标题');
setTimeout(() => {
notif.close();
}, 500);
3.事件const notif = new Notification('这是标题');
notif.onclick = () => {
console.log('点击了通知');
};
notif.onclose = () => {
console.log('关闭了通知');
};
notif.onerror = () => {
console.log('通知出错');
};
notif.onshow = () => {
console.log('显示了通知');
};
基础Demo// WebSocket,用node运行此文件
const express = require('express');
const WebSocket = require('ws');
const WebSocketServer = WebSocket.WebSocketServer;
const app = express();
app.get('/', (req, res) => {
res.send({
ok: 1,
});
});
app.listen(3000, () => {
console.log('express start');
});
const wss = new WebSocketServer({port: 8080});
wss.on('connection', function connection(ws) {
ws.on('error', console.error);
ws.on('message', function message(data) {
console.log('received: %s', data);
});
// 每4s发送一条消息
setInterval(() => {
ws.send('something', {binary: false});
}, 4000);
});
// 两个关键方法
// 请求用户通知权限,需要用户点击允许
const notificationSet = () => {
if (!('Notification' in window)) {
// 检查浏览器是否支持通知,不可用则显示页面提示
setVisible(true);
} else if (Notification.permission === 'granted') {
// 检查是否已授予通知权限;如果是的话,创建一个默认通知,表明后续采用此种方式提示用户
initNotifyPermission();
} else if (Notification.permission === 'default') {
// 默认则征求用户的许可
Notification.requestPermission().then((permission) => {
// 如果用户接受,我们就创建一个通知
if (permission === 'granted') {
initNotifyPermission();
} else {
// 用户选择拒绝,则进行message提示
messageApi.open({
type: 'error',
content:
'您禁用了该页面发出通知,这将导致您收不到后续更新提示,请在浏览器设置中放开该页面通知权限',
duration: 10,
});
}
});
}
};
// 建立websocket连接
const webSocketSet = () => {
const socket = new WebSocket('ws://localhost:8080');
// 监听连接
socket.addEventListener('open', function () {
socket.send('Hello Server!');
});
// 监听后端传来的消息
socket.addEventListener('message', function (event) {
// 用新增一行table来标识接受到了消息
setTableData((data) => [
...data,
{
key: Math.random().toString(36).slice(-6),
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
]);
// 发出通知
new Notification('数据已更新,请立即查看', {
body: '具体信息。。。',
icon: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
requireInteraction: true,
image:
'https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png',
});
});
};
// 堆代码 duidaima.com
// 进入页面请求页面通知权限、建立WebSocket链接
useEffect(() => {
notificationSet();
webSocketSet();
}, []);
限制


上面的基础Demo已经能实现接收后端消息后更新页面并发出通知,但是如果你运行了上面的代码,会发现还存在一些问题:
1.由于设置的是通知不自动关闭,发出多个通知之后,需要手动关闭,很麻烦
解决方式:发出的通知收集到一个数组里面,统一管理。notif.onclick = () => {
window.focus();
};
3.页面可见的时候不需要发出通知,不可见才发出通知if (document.visibilityState !== 'visible') {
// 发出通知
}
4.页面可见时,关闭之前的通知document.addEventListener('visibilitychange', () => {
// 关闭之前的通知
});
5.没有通知音效,提醒效果不明显<audio
src={warmTipsAudio}
style={{ display: 'none' }}
ref={warmTipsAudioRef}
></audio>
warmTipsAudioRef.current.play();