如何无刷新动态更新页面内容?避免手动编写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">×</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">×</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
相关产品推荐
相关产品推荐

