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

如何在新增数据库记录并显示到表格后触发带音效的弹窗通知

实现新增记录弹窗+音效通知

需求说明

现有代码已实现数据库数据实时同步到前端表格,需新增功能:当数据库添加新记录并同步到表格后,弹出带音效的弹窗通知用户。

修改后的代码

1. fetch.php(后端优化:识别新增记录)

<?php
error_reporting(0);
// 适配SSE技术
header("Cache-Control: no-store");
header("Content-Type: text/event-stream");
// 连接数据库
include("db_connection.php");

// 记录上次的数据行数和完整数据
$prevCount = 0;
$prevData = [];

while(true){
    // 从数据库获取数据,按ID倒序以便快速获取最新记录
    $result = $con->query("SELECT * FROM data ORDER BY id DESC");
    $currentData = [];
    $currentCount = 0;
    
    if($result->num_rows > 0){
        $currentCount = $result->num_rows;
        while($row = $result->fetch_assoc()){
            $currentData[] = $row;
        }
        // 反转数组恢复正序
        $currentData = array_reverse($currentData);
    }
    
    $response = [
        'allData' => $currentData,
        'newRecords' => []
    ];
    
    // 判断是否有新增记录
    if($currentCount > $prevCount){
        // 计算新增数量,提取新增的记录
        $newCount = $currentCount - $prevCount;
        // 倒序数据中前$newCount条为新增记录,反转回正序
        $newRecords = array_slice(array_reverse($currentData), 0, $newCount);
        $response['newRecords'] = $newRecords;
    }
    
    $responseJson = json_encode($response);
    // 只有数据变化时才推送
    if($responseJson !== json_encode(['allData' => $prevData, 'newRecords' => []])){
        echo "data:". $responseJson. "\n\n";
        $prevCount = $currentCount;
        $prevData = $currentData;
    }
    
    ob_end_flush();
    flush();
    sleep(1);
}
?>

2. index.html(前端新增弹窗+音效逻辑)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实时数据库数据同步</title>
    <style>
        .container{
            max-width: 900px;
            font-family: sans-serif;
            margin: auto;
        }
        h1{
            text-align: center;
            margin-bottom: 30px;
        }
        table{
            width: 100%;
            border-spacing: 0px;
        }
        table th,
        table td{
            padding: 15px 0px;
            border-bottom: 1px solid #cacaca;
            text-align: left;
        }
        td:last-child{
            width: 600px;
        }
        /* 弹窗样式 */
        .notification-modal{
            position: fixed;
            top: 20px;
            right: 20px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.15);
            padding: 16px 20px;
            z-index: 9999;
            transform: translateX(100%);
            transition: transform 0.3s ease;
        }
        .notification-modal.show{
            transform: translateX(0);
        }
        .notification-modal .title{
            font-weight: bold;
            margin-bottom: 8px;
            color: #2d3748;
        }
        .notification-modal .content{
            color: #4a5568;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>实时数据库数据同步</h1>
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>名称</th>
                    <th>消息</th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>

    <!-- 通知弹窗 -->
    <div class="notification-modal" id="notificationModal">
        <div class="title">新记录通知</div>
        <div class="content" id="notificationContent"></div>
    </div>

    <!-- 音效元素 -->
    <audio id="notificationSound" src="notification.mp3" preload="auto"></audio>

    <script>
        const source = new EventSource("fetch.php");
        const dataContainer = document.querySelector('tbody');
        const notificationModal = document.getElementById('notificationModal');
        const notificationContent = document.getElementById('notificationContent');
        const notificationSound = document.getElementById('notificationSound');

        // 显示通知弹窗
        function showNotification(records){
            // 拼接新增记录内容
            let content = '';
            records.forEach(record => {
                content += `<p><strong>ID:</strong> ${record.id} | <strong>名称:</strong> ${record.name}</p>`;
            });
            notificationContent.innerHTML = content;
            
            // 播放音效
            notificationSound.play().catch(err => {
                // 处理自动播放限制(需用户先和页面交互)
                console.log("音效播放失败:", err);
            });
            
            // 显示弹窗
            notificationModal.classList.add('show');
            
            // 3秒后隐藏弹窗
            setTimeout(() => {
                notificationModal.classList.remove('show');
            }, 3000);
        }

        source.onmessage = function (event) {
            const response = JSON.parse(event.data);
            const arrayData = response.allData;
            
            // 更新表格
            dataContainer.innerHTML = '';
            arrayData.forEach(e => {
                dataContainer.innerHTML += `
                    <tr>
                        <td>${e.id}</td>
                        <td>${e.name}</td>
                        <td>${e.message}</td>
                    </tr>
                `;
            });
            
            // 如果有新增记录,触发通知
            if(response.newRecords.length > 0){
                showNotification(response.newRecords);
            }
        };

        // 处理SSE连接错误
        source.onerror = function(error) {
            console.error("SSE连接错误:", error);
            source.close();
        };
    </script>
</body>
</html>

3. db_connection.php(无需修改,保留原逻辑)

<?php
$server = "localhost";
$user = "root";
$pass = "";
// 请先创建数据库
$database = "yt_test"; 
$con = mysqli_connect($server, $user, $pass);
if(!$con){
    echo '服务器连接失败';
}
$db = mysqli_select_db($con, $database);
if(!$db){
    echo '数据库连接失败';
}
?>

额外说明

  1. 音效文件:需准备一个名为notification.mp3的音效文件,放在与index.html同目录下,或修改audio标签的src路径指向你的音效文件。
  2. 自动播放限制:现代浏览器要求用户与页面有交互(如点击页面)后才能自动播放音频,若需无交互播放,需引导用户先进行一次页面操作。
  3. 性能优化:后端通过对比记录行数判断新增,避免全量数据对比;按ID倒序获取数据,快速提取新增记录,提升同步效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:33:19