实时数据展示中数据库新增数据触发60秒倒计时的实现问询
实时数据展示+新数据触发倒计时解决方案
问题概述
实现index.php通过AJAX每5秒轮询system.php获取users_logs表数据并展示;当数据库插入新数据时,触发60秒倒计时(弹窗/模态框),倒计时结束自动关闭,等待下一次新增数据再次触发。当前尝试的判断逻辑未实现预期效果。
现有代码
Countdown.php
<script> function countDown(secs,elem) { var element = document.getElementById(elem); element.innerHTML = "Please wait for "+secs+" seconds"; if(secs < 1) { clearTimeout(timer); element.innerHTML = '<h2>Countdown Complete!</h2>'; element.innerHTML += '<a href="#">Click here now</a>'; } secs--; var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000); } </script> <div id="status"></div> <script>countDown(60,"status");</script>
index.php
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Real Time Data Display</title> </head> <body onload = "table();"> <script type="text/javascript"> function table(){ const xhttp = new XMLHttpRequest(); xhttp.onload = function(){ document.getElementById("table").innerHTML = this.responseText; } xhttp.open("GET", "system.php"); xhttp.send(); } setInterval(function(){ table(); }, 5000); </script> <div id="table"></div> </body> </html>
system.php(原版本)
<?php $conn = mysqli_connect("localhost", "root", "", "user"); $rows = mysqli_query($conn, "SELECT * FROM users_logs"); ?> <table border = 1 cellpadding = 10> <tr> <td>#</td> <td>user</td> <td>Plate</td> <td>age</td> <td>email</td> </tr> <?php $i = 1; ?> <?php foreach($rows as $row) : ?> <tr> <td><?php echo $i++; $link = "<script>window.open('http://localhost/realtimedatadisplay/countdown.php')</script>"; echo $link; ?> </td> <td><?php echo $row["user"]; ?></td> <td><?php echo $row["plate"]; ?></td> <td><?php echo $row["age"]; ?></td> <td><?php echo $row["email"]; ?></td> </tr> <?php endforeach; ?> </table>
尝试的判断逻辑代码
<?php $conn = mysqli_connect("localhost", "root", "", "user"); $rows = mysqli_query($conn, "SELECT * FROM users_logs"); $query = "SELECT * FROM users_logs"; $connect = mysqli_connect("localhost", "root", "", "user"); $result = mysqli_query($connect, $query); $link = "<script>window.open('http://localhost/realtimedatadisplay/countdown.php')</script>"; $num_rows = mysqli_num_rows($result); if(!isset($_SESSION['user'])) { $check = $_SESSION['user'] = $num_rows; } else { $check = $_SESSION['user']; } echo $num_rows; if($num_rows > $check ) { $check = $_SESSION['user'] = $num_rows; echo "new user"; echo $link; } else { echo "wait"; } ?>
解决方案
1. 后端逻辑修正(system.php)
用自增ID判断新数据代替行数统计(行数可能因删除操作变化,ID自增更可靠),返回JSON格式数据包含表格HTML、是否有新数据、当前最大ID:
<?php $conn = mysqli_connect("localhost", "root", "", "user"); if (!$conn) { die("连接失败: " . mysqli_connect_error()); } // 获取前端传递的上次最大ID $lastId = isset($_GET['lastId']) ? intval($_GET['lastId']) : 0; // 查询所有数据并获取当前最大ID $result = mysqli_query($conn, "SELECT * FROM users_logs ORDER BY id DESC"); $maxId = 0; $tableHtml = '<table border="1" cellpadding="10"> <tr> <td>#</td> <td>user</td> <td>Plate</td> <td>age</td> <td>email</td> </tr>'; $i = 1; while ($row = mysqli_fetch_assoc($result)) { if ($row['id'] > $maxId) { $maxId = $row['id']; } $tableHtml .= '<tr> <td>' . $i++ . '</td> <td>' . $row["user"] . '</td> <td>' . $row["plate"] . '</td> <td>' . $row["age"] . '</td> <td>' . $row["email"] . '</td> </tr>'; } $tableHtml .= '</table>'; // 判断是否有新数据 $hasNewData = $maxId > $lastId ? true : false; // 返回JSON格式响应 echo json_encode([ 'tableHtml' => $tableHtml, 'hasNewData' => $hasNewData, 'maxId' => $maxId ]); mysqli_close($conn); ?>
2. 前端逻辑优化(index.php)
- 记录上次获取的最大ID,每次轮询传递给后端
- 新增模态框代替新窗口展示倒计时,优化交互体验
- 避免重复触发倒计时(判断模态框是否已打开)
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Real Time Data Display</title> <style> /* 模态框样式 */ .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; } .countdown-modal { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 2rem; background: #fff; border-radius: 8px; box-shadow: 0 0 15px rgba(0,0,0,0.2); z-index: 1000; } </style> </head> <body onload="init()"> <div id="table"></div> <!-- 倒计时模态框 --> <div class="modal-overlay" id="modalOverlay"></div> <div class="countdown-modal" id="countdownModal"> <div id="status"></div> </div> <script type="text/javascript"> let lastMaxId = 0; function init() { loadData(); setInterval(loadData, 5000); } function loadData() { const xhttp = new XMLHttpRequest(); xhttp.onload = function() { const response = JSON.parse(this.responseText); // 更新表格内容 document.getElementById("table").innerHTML = response.tableHtml; // 触发倒计时:有新数据且模态框未打开 if (response.hasNewData && document.getElementById('countdownModal').style.display !== 'block') { showCountdown(); } // 更新上次最大ID lastMaxId = response.maxId; } xhttp.open("GET", `system.php?lastId=${lastMaxId}`); xhttp.send(); } function showCountdown() { // 显示模态框 document.getElementById('modalOverlay').style.display = 'block'; document.getElementById('countdownModal').style.display = 'block'; // 初始化倒计时 countDown(60, "status"); } function countDown(secs, elem) { const element = document.getElementById(elem); element.innerHTML = `请等待 ${secs} 秒`; if (secs < 1) { clearTimeout(timer); element.innerHTML = '<h2>倒计时结束!</h2>'; // 关闭模态框 document.getElementById('modalOverlay').style.display = 'none'; document.getElementById('countdownModal').style.display = 'none'; return; } secs--; const timer = setTimeout(() => countDown(secs, elem), 1000); } </script> </body> </html>
3. 关键改进点
- 用自增ID判断新数据:避免因删除操作导致的行数变化误判,逻辑更可靠
- 前端控制触发逻辑:避免后端输出脚本带来的重复执行问题
- 模态框代替新窗口:符合现代网页交互习惯,用户体验更好
- 分离数据与业务:后端仅负责数据处理,前端负责交互逻辑,代码更易维护
内容的提问来源于stack exchange,提问作者SpawnRivera
相关产品推荐
相关产品推荐

