You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP+JavaScript通知关闭后刷新重现问题的解决方法咨询

解决通知刷新后重复弹出的问题

你的问题根源在于每次页面刷新时,PHP都会重新输出所有查询到的通知对应的JavaScript代码,浏览器执行后就会再次触发通知——完全没记录用户已经关闭过哪些通知。要解决这个问题,我们需要在浏览器端记录用户已处理的通知ID,避免重复触发,具体可以按下面的步骤来:

核心思路

  1. 给每条通知绑定数据库里的唯一ID(比如parent_help表的主键id),用来区分不同的通知
  2. 使用浏览器的localStorage(持久化,关闭浏览器后仍保留)或sessionStorage(仅当前会话有效)存储用户已关闭的通知ID
  3. 触发通知前先检查:如果该通知ID已经在存储中,就跳过;否则才弹出通知,并且在通知关闭时把ID存入存储

修改后的代码

<?php
// 先一次性请求通知权限,避免循环里重复请求
?>
<script>
// 全局请求通知权限,只执行一次
function requestNotificationPermission() {
    if (!("Notification" in window)) {
        alert("This browser does not support system notifications");
        return false;
    }
    if (Notification.permission === "granted") {
        return true;
    } else if (Notification.permission !== 'denied') {
        return new Promise((resolve) => {
            Notification.requestPermission(function (permission) {
                resolve(permission === "granted");
            });
        });
    }
    return false;
}

// 检查通知是否已经被处理过
function hasNotificationBeenShown(notificationId) {
    const shownIds = JSON.parse(localStorage.getItem('shownNotifications')) || [];
    return shownIds.includes(notificationId);
}

// 标记通知为已处理
function markNotificationAsShown(notificationId) {
    const shownIds = JSON.parse(localStorage.getItem('shownNotifications')) || [];
    if (!shownIds.includes(notificationId)) {
        shownIds.push(notificationId);
        localStorage.setItem('shownNotifications', JSON.stringify(shownIds));
    }
}

// 初始化权限,然后处理所有通知
async function initNotifications() {
    const hasPermission = await requestNotificationPermission();
    if (!hasPermission) return;

    // 遍历所有通知数据(这里把PHP循环的内容转成JS数组,更高效)
    const notifications = <?php
        $notifications = [];
        $select_children_query = mysqli_query($con, "SELECT * FROM parent_help");
        while($row = mysqli_fetch_assoc($select_children_query)) {
            $notifications[] = [
                'id' => $row['id'],
                'title' => 'TITLE OF NOTIFICATION', // 可以换成数据库里的标题字段
                'body' => "Hey! You are on notice!", // 换成数据库里的内容字段
                'icon' => 'http://carnes.cc/jsnuggets_avatar.jpg'
            ];
        }
        echo json_encode($notifications);
    ?>;

    notifications.forEach(notifyData => {
        if (hasNotificationBeenShown(notifyData.id)) return;

        const notification = new Notification(notifyData.title, {
            icon: notifyData.icon,
            body: notifyData.body,
        });

        notification.onclick = function () {
            window.open("http://carnes.cc");
            markNotificationAsShown(notifyData.id);
        };

        // 关闭通知时也标记为已处理
        notification.onclose = function () {
            markNotificationAsShown(notifyData.id);
        };
    });
}

// 页面加载后执行
initNotifications();
</script>

关键修改说明

  • 权限请求优化:把通知权限请求放在全局,只执行一次,避免循环里多次弹出权限请求弹窗,提升用户体验
  • 唯一ID绑定:用数据库里的id作为每条通知的唯一标识,确保能准确区分不同通知
  • 本地存储记录:localStorage用来持久化保存已处理的通知ID,用户关闭通知或点击后,该ID会被存入,下次刷新页面时就不会再弹出这条通知
  • 代码结构优化:把PHP查询到的所有通知数据转成JS数组,再用JS遍历处理,比原来循环输出多个<script>标签更高效、更易维护

如果希望仅在当前浏览器会话内避免重复弹出(关闭浏览器后重新打开会再次显示),只需把代码里的localStorage换成sessionStorage即可。

内容的提问来源于stack exchange,提问作者user9388372

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:48:05