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

实时数据展示中数据库新增数据触发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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:35:00