如何在新增数据库记录并显示到表格后触发带音效的弹窗通知
实现新增记录弹窗+音效通知
需求说明
现有代码已实现数据库数据实时同步到前端表格,需新增功能:当数据库添加新记录并同步到表格后,弹出带音效的弹窗通知用户。
修改后的代码
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 '数据库连接失败'; } ?>
额外说明
- 音效文件:需准备一个名为
notification.mp3的音效文件,放在与index.html同目录下,或修改audio标签的src路径指向你的音效文件。 - 自动播放限制:现代浏览器要求用户与页面有交互(如点击页面)后才能自动播放音频,若需无交互播放,需引导用户先进行一次页面操作。
- 性能优化:后端通过对比记录行数判断新增,避免全量数据对比;按ID倒序获取数据,快速提取新增记录,提升同步效率。
内容的提问来源于stack exchange,提问作者yasin1364
相关产品推荐
相关产品推荐

