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

如何无刷新动态更新页面内容?避免手动编写HTML的方案

问题描述

我有一个展示用户数据的表格,管理员可通过弹窗新增用户。功能可用但需刷新页面才能看到新行。我可以在事件处理器中手动编写HTML(如下代码),但这并非最佳实践——当行包含大量数据或嵌套弹窗时操作极为繁琐。实际项目中表格数据来自数据库,想了解如何无需页面刷新、也无需手动编写HTML来动态修改页面内容?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <title>Admin Page</title>
</head>
<body>
<div class="container">
    <div class="row">
        <table class="table table-hover text-center">
                  <thead>
                        <tr>
                            <th scope="col">Name</th>
                            <th scope="col">Last name</th>
                            <th scope="col">Department</th>
                        </tr>
                  </thead>
                  <tbody>
                        <tr>
                            <td>John</td>
                            <td>Doe</td>
                            <td>IT</td>
                        </tr>
                        <tr>
                            <td>Jane</td>
                            <td>Doe</td>
                            <td>HR</td>
                        </tr>
                 </tbody>
          </table>
          <a href="#" class="btn btn-outline-primary" data-toggle="modal" data-target="#add-new-user">Add new user</a>
          <div class="modal" id="add-new-user">
              <div class="modal-dialog modal-centered">
                  <div class="modal-content">
                      <div class="modal-header">
                          <h3 class="modal-title text-center w-100">Fill in the forms</h3>
                          <button type="button" class="close" data-dismiss="modal">&times;</button>
                      </div>
                      <div class="modal-body">
                          <form>
                              <div class="form-group">
                                  <label for="name">Name: </label>
                                  <input id="name" name="name" type="text" class="form-control" />
                              </div>

                              <div class="form-group">
                                  <label for="last-name">Last name: </label>
                                  <input id="last-name" name="last-name" type="text" class="form-control" />
                              </div>

                              <div class="form-group">
                                  <label for="department">Department: </label>
                                  <select id="department" name="department" class="form-control">
                                      <option value="IT">IT</option>
                                      <option value="HR">HR</option>
                                      <option value="accounting">Accounting</option>
                                  </select>
                              </div>

                              <input type="submit" class="btn btn-primary d-flex ml-auto" value="Submit" />
                          </form>
                      </div>
                  </div>
              </div>
          </div>
      </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
$(document).ready(function () {
$('form').on('submit', async function (event) {
    event.preventDefault();
    $('tbody').append(
    `<tr>
         <td>
             ${$(this).find('[name=name]').val()}
         </td>
         <td>
             ${$(this).find('[name=last-name]').val()}
         </td>
         <td>
             ${$(this).find('[name=department]').val()}
         </td>
     </tr>`
    );
    $(this).closest('.modal').modal('hide');
});
});
</script>
</body>
</html>

解决方案

1. 使用HTML <template> 元素(原生方案,无需框架)

把表格行的结构定义在<template>标签里,需要新增行时克隆模板,填充数据后插入DOM,既避免手动拼接HTML,又保证结构可维护。

修改后的代码:

首先在HTML的<body>末尾添加模板:

<template id="user-row-template">
  <tr>
    <td class="user-name"></td>
    <td class="user-last-name"></td>
    <td class="user-department"></td>
  </tr>
</template>

然后修改JS的提交事件处理逻辑:

$(document).ready(function () {
  const rowTemplate = document.getElementById('user-row-template');
  
  $('form').on('submit', function (event) {
    event.preventDefault();
    
    // 克隆模板内容
    const newRow = rowTemplate.content.cloneNode(true);
    // 填充数据
    newRow.querySelector('.user-name').textContent = $(this).find('[name=name]').val();
    newRow.querySelector('.user-last-name').textContent = $(this).find('[name=last-name]').val();
    newRow.querySelector('.user-department').textContent = $(this).find('[name=department]').val();
    
    // 插入到表格tbody
    $('tbody').append(newRow);
    
    $(this).closest('.modal').modal('hide');
    // 清空表单
    $(this)[0].reset();
  });
});

2. 使用原生DOM API创建元素(纯JS操作,无字符串拼接)

通过document.createElement逐行创建DOM节点,完全避免HTML字符串拼接,更安全(防止XSS),适合复杂结构的场景。

修改后的JS逻辑:

$(document).ready(function () {
  $('form').on('submit', function (event) {
    event.preventDefault();
    
    // 获取表单数据
    const name = $(this).find('[name=name]').val();
    const lastName = $(this).find('[name=last-name]').val();
    const department = $(this).find('[name=department]').val();
    
    // 创建行和单元格
    const tr = document.createElement('tr');
    
    const nameTd = document.createElement('td');
    nameTd.textContent = name;
    
    const lastNameTd = document.createElement('td');
    lastNameTd.textContent = lastName;
    
    const deptTd = document.createElement('td');
    deptTd.textContent = department;
    
    // 组装行
    tr.appendChild(nameTd);
    tr.appendChild(lastNameTd);
    tr.appendChild(deptTd);
    
    // 插入表格
    $('tbody')[0].appendChild(tr);
    
    $(this).closest('.modal').modal('hide');
    $(this)[0].reset();
  });
});

3. 前端框架(数据驱动视图,大型项目首选)

在实际项目中,使用Vue、React这类框架时,核心逻辑是维护数据源,视图自动更新,完全不需要手动操作DOM。以Vue为例:

简化示例:

<div id="app" class="container">
  <table class="table table-hover text-center">
    <thead>
      <tr>
        <th>Name</th>
        <th>Last name</th>
        <th>Department</th>
      </tr>
    </thead>
    <tbody>
      <!-- 直接循环渲染数据源 -->
      <tr v-for="user in users" :key="user.id">
        <td>{{ user.name }}</td>
        <td>{{ user.lastName }}</td>
        <td>{{ user.department }}</td>
      </tr>
    </tbody>
  </table>
  
  <button class="btn btn-outline-primary" data-toggle="modal" data-target="#add-new-user">Add new user</button>
  
  <!-- 弹窗表单 -->
  <div class="modal" id="add-new-user">
    <div class="modal-dialog modal-centered">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title text-center w-100">Fill in the forms</h3>
          <button type="button" class="close" data-dismiss="modal">&times;</button>
        </div>
        <div class="modal-body">
          <form @submit.prevent="addUser">
            <div class="form-group">
              <label>Name: </label>
              <input v-model="newUser.name" type="text" class="form-control" />
            </div>
            <div class="form-group">
              <label>Last name: </label>
              <input v-model="newUser.lastName" type="text" class="form-control" />
            </div>
            <div class="form-group">
              <label>Department: </label>
              <select v-model="newUser.department" class="form-control">
                <option value="IT">IT</option>
                <option value="HR">HR</option>
                <option value="accounting">Accounting</option>
              </select>
            </div>
            <button type="submit" class="btn btn-primary d-flex ml-auto">Submit</button>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
new Vue({
  el: '#app',
  data: {
    users: [
      { id: 1, name: 'John', lastName: 'Doe', department: 'IT' },
      { id: 2, name: 'Jane', lastName: 'Doe', department: 'HR' }
    ],
    newUser: { name: '', lastName: '', department: 'IT' }
  },
  methods: {
    addUser() {
      // 新增用户到数据源,视图自动更新
      this.users.push({
        id: Date.now(), // 临时用时间戳当ID,实际用后端返回的ID
        ...this.newUser
      });
      // 清空表单
      this.newUser = { name: '', lastName: '', department: 'IT' };
      // 关闭弹窗
      $('#add-new-user').modal('hide');
    }
  }
});
</script>

这种方式下,你只需要关注数据的变化,DOM的更新完全由框架处理,尤其适合复杂页面和大型项目。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:04:54