在前端开发中,桌面通知可以让网页在用户未聚焦当前页面时也能传递重要信息,javascript实现桌面通知主要依赖浏览器提供的Notification API,而通知系统的设计则需要结合业务场景做更全面的规划。

一、javascript实现桌面通知的基础用法
1. 检查浏览器支持与请求权限
Notification API并非所有浏览器都支持,使用前需要先做兼容性判断,同时发送通知前必须获取用户的授权,否则通知无法展示。浏览器权限状态分为三种:granted(已授权)、denied(已拒绝)、default(未选择)。
请求权限的代码示例如下:
// 检查浏览器是否支持Notification API
if (!("Notification" in window)) {
console.log("当前浏览器不支持桌面通知功能");
} else {
// 如果权限状态是未选择,主动请求用户授权
if (Notification.permission === "default") {
Notification.requestPermission().then((permission) => {
if (permission === "granted") {
console.log("用户已授权通知权限");
} else if (permission === "denied") {
console.log("用户拒绝了通知权限");
}
});
}
}
2. 发送基础桌面通知
当用户授权后,就可以创建Notification实例来发送通知,基础通知可以设置标题、内容、图标等基础属性。
发送基础通知的代码示例:
// 假设已经获取到用户授权,发送基础通知
function sendBasicNotification() {
if (Notification.permission === "granted") {
const notification = new Notification("新消息提醒", {
body: "您有一条新的订单消息待处理", // 通知正文内容
icon: "https://ipipp.com/notification_icon.png", // 通知图标地址
tag: "order-notify", // 通知标识,相同tag的通知会替换而不是新增
requireInteraction: false // 是否保持通知不自动关闭,默认false
});
// 点击通知的回调
notification.onclick = () => {
console.log("用户点击了通知");
// 可以跳转到对应页面
window.focus();
notification.close();
};
// 通知关闭的回调
notification.onclose = () => {
console.log("通知已关闭");
};
}
}
3. 进阶通知功能
除了基础属性,还可以设置通知的振动模式、声音、动作按钮等进阶功能,不过部分属性需要浏览器支持。
带动作按钮的通知示例:
function sendAdvancedNotification() {
if (Notification.permission === "granted") {
const notification = new Notification("任务提醒", {
body: "您有3个待处理的审批任务",
icon: "https://ipipp.com/task_icon.png",
actions: [
{ action: "view", title: "查看详情" },
{ action: "ignore", title: "忽略" }
],
vibrate: [200, 100, 200] // 振动模式,仅移动端支持
});
notification.onaction = (event) => {
if (event.action === "view") {
console.log("用户点击了查看详情按钮");
// 跳转到审批页面
} else if (event.action === "ignore") {
console.log("用户点击了忽略按钮");
}
notification.close();
};
}
}
二、javascript通知系统的设计思路
1. 核心模块划分
一个完整的通知系统需要包含以下核心模块:
- 权限管理模块:负责检测浏览器支持情况、请求和管理用户通知权限,处理权限被拒绝后的引导逻辑。
- 通知队列模块:当短时间内有多个通知需要发送时,对通知进行排队,避免同时弹出大量通知打扰用户。
- 规则匹配模块:根据业务规则判断是否需要发送通知,比如用户是否在当前页面、消息优先级是否达到发送标准等。
- 状态管理模块:记录通知的发送状态、用户操作状态,同步到后端做数据留存。
- 交互处理模块:处理通知的点击、关闭、动作按钮点击等交互事件,执行对应的业务逻辑。
2. 通知类型与优先级设计
可以根据业务场景划分不同的通知类型,设置对应的优先级,优先级高的通知可以优先发送,甚至可以突破免打扰规则。
通知类型与优先级参考表:
| 通知类型 | 优先级 | 触发场景 | 发送规则 |
|---|---|---|---|
| 紧急告警 | 高 | 系统故障、资金异常 | 无论用户是否在当前页面都发送,保持通知不自动关闭 |
| 业务提醒 | 中 | 订单更新、审批通知 | 用户不在当前页面时发送,自动关闭 |
| 营销推送 | 低 | 活动通知、优惠提醒 | 仅用户开启营销通知权限时发送,每天最多推送2次 |
3. 兼容性处理与优化
不同浏览器对Notification API的支持程度不同,需要做对应的兼容处理:
- 对于不支持Notification API的浏览器,可以降级为页面内弹窗提示。
- 部分浏览器要求通知请求必须在用户交互行为(比如点击)之后触发,需要把权限请求绑定到用户操作上。
- 可以设置免打扰时段,在用户设置的免打扰时间内不发送低优先级通知。
- 通知图标和资源的地址尽量使用可靠域名,避免因为资源加载失败导致通知显示异常。
4. 简单通知系统实现示例
以下是一个简化的通知系统实现代码:
class NotificationSystem {
constructor() {
this.permission = Notification.permission;
this.notifyQueue = [];
this.isProcessingQueue = false;
this.disturbPeriod = null; // 免打扰时段,格式为{start: 22, end: 8}表示22点到次日8点
}
// 初始化权限
async initPermission() {
if (!("Notification" in window)) {
console.log("浏览器不支持桌面通知");
return false;
}
if (this.permission === "default") {
const result = await Notification.requestPermission();
this.permission = result;
}
return this.permission === "granted";
}
// 检查是否在免打扰时段
checkDisturb() {
if (!this.disturbPeriod) return false;
const nowHour = new Date().getHours();
const { start, end } = this.disturbPeriod;
if (start > end) {
// 跨天的情况,比如22点到次日8点
return nowHour >= start || nowHour < end;
} else {
return nowHour >= start && nowHour < end;
}
}
// 发送通知
async sendNotify({ title, body, icon, priority = "medium", actions = [] }) {
const hasPermission = await this.initPermission();
if (!hasPermission) return;
// 低优先级通知在免打扰时段不发送
if (priority === "low" && this.checkDisturb()) {
console.log("当前处于免打扰时段,低优先级通知暂不发送");
return;
}
// 高优先级通知直接发送,其他加入队列
if (priority === "high") {
this._createNotify({ title, body, icon, actions });
} else {
this.notifyQueue.push({ title, body, icon, actions });
this._processQueue();
}
}
// 处理通知队列
_processQueue() {
if (this.isProcessingQueue || this.notifyQueue.length === 0) return;
this.isProcessingQueue = true;
const notifyItem = this.notifyQueue.shift();
this._createNotify(notifyItem);
// 间隔1秒发送下一个通知,避免同时弹出多个
setTimeout(() => {
this.isProcessingQueue = false;
this._processQueue();
}, 1000);
}
// 创建通知实例
_createNotify({ title, body, icon, actions }) {
const notification = new Notification(title, {
body,
icon: icon || "https://ipipp.com/default_notify.png",
actions,
tag: `notify-${Date.now()}`
});
notification.onclick = () => {
console.log("通知被点击");
window.focus();
notification.close();
};
}
}
// 使用示例
const notifySystem = new NotificationSystem();
// 设置免打扰时段为22点到次日8点
notifySystem.disturbPeriod = { start: 22, end: 8 };
// 发送中优先级通知
notifySystem.sendNotify({
title: "订单更新",
body: "您的订单已发货",
priority: "medium"
});
三、注意事项
使用桌面通知时需要注意,不要频繁发送通知,否则用户可能会直接拒绝通知权限。另外通知的内容要简洁明确,让用户一眼就能知道通知的核心信息,动作按钮也不要设置过多,避免用户选择困难。如果通知需要跳转到特定页面,要确保跳转逻辑在通知的onclick回调中正确执行,同时关闭通知避免残留。
javascript桌面通知Notification_API通知系统前端交互修改时间:2026-07-16 10:03:40