ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

jQuery+Bootstrap5本地CRUD后台管理页实战

jQuery+Bootstrap5本地CRUD后台管理页实战 简介本资源是一份面向前端初学者与Web开发入门者的实战型教学资料聚焦jQuery与Bootstrap协同实现后台管理页面核心CRUD功能增删改查适用于快速搭建轻量级管理系统界面或学习前后端交互基础逻辑。压缩包为单文件PDF文档77KB完整呈现了从HTML结构、Bootstrap样式集成、jQuery事件绑定、表单数据获取与提交到Ajax调用后端PHP接口的全流程代码示例与关键注释含active_list.html前端模板及show_upload_info、act_resize_img等实用工具函数说明。内容覆盖input/textarea值操作、元素显隐控制、表单序列化、模态框交互、图片预览适配及日期控件集成等高频开发场景零耦合、开箱即用无需构建工具。目前已有803人学习下载适合希望掌握原生jQueryBootstrap组合开发模式、理解CRUD前端实现细节的开发者快速上手与复用。1. 用 jQuery Bootstrap 快速搭出能真跑的后台管理页不是静态模板而是带本地数据模拟的 CRUD 全流程你打开一个「后台管理页面」Demo发现表格里空空如也点新增弹窗没反应删一条数据后页面不刷新——这不是代码写错了是缺了数据驱动闭环。本例不连真实后端但用 jQuery 操作 DOM、Bootstrap 渲染组件、localStorage 模拟数据库完整走通「新增→列表渲染→编辑→删除→状态同步」五步链路。适合刚学完 jQuery 事件和 Bootstrap 表单组件、正卡在「怎么把它们串起来」的前端新手也适合后端开发者快速补上前端交互逻辑避免把 CRUD 写成纯 HTML 静态页。重点不在炫技而在每一步都可验证新增后表格立刻多一行删完立即消失编辑保存后原行内容实时更新——所有操作都有 DOM 反馈、有数据落盘、有错误提示。2. 用 Bootstrap 5 构建响应式管理页骨架jQuery 绑定事件并接管表单交互2.1 页面结构用 Bootstrap 5 的 container、card 和 table 实现标准后台布局Bootstrap 5 已移除 jQuery 依赖但本例仍用 jQuery 处理动态逻辑因此需同时引入 Bootstrap CSS 和 JS含 Popper再单独加载 jQuery。页面主体采用container-fluidrowcol布局顶部为搜索栏与新增按钮中部为数据表格底部为分页占位本例暂不实现分页但留出结构。关键结构如下!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title用户管理后台/title !-- Bootstrap 5.3 CSS -- link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.3.3/dist/css/bootstrap.min.css relstylesheet /head body div classcontainer-fluid mt-4 !-- 顶部操作区 -- div classrow mb-3 div classcol-md-6 div classinput-group input typetext idsearchInput classform-control placeholder按姓名搜索... button classbtn btn-outline-secondary idsearchBtn搜索/button /div /div div classcol-md-6 text-md-end button classbtn btn-primary>// app.js let users JSON.parse(localStorage.getItem(users)) || [ { id: 1, name: 张三, email: zhangsanexample.com, department: 技术部 }, { id: 2, name: 李四, email: lisiexample.com, department: 产品部 }, { id: 3, name: 王五, email: wangwuexample.com, department: 运营部 } ]; // 渲染用户列表到 tbody function renderUserList() { const tbody $(#userTableBody); tbody.empty(); // 清空旧数据 users.forEach(user { const row tr>// 表单验证状态监听Bootstrap 5 自动添加 is-invalid 类 $(#userForm).on(input, input, select, function() { const field $(this); const feedback field.next(.invalid-feedback); if (field[0].checkValidity()) { field.removeClass(is-invalid); feedback.hide(); } else { field.addClass(is-invalid); feedback.show(); } }); // 保存按钮点击事件 $(#saveUserBtn).on(click, function() { const form $(#userForm)[0]; if (!form.checkValidity()) { // 触发 Bootstrap 5 原生验证提示 form.classList.add(was-validated); return; } const id $(#editId).val(); const name $(#nameInput).val().trim(); const email $(#emailInput).val().trim(); const dept $(#deptInput).val(); if (id) { // 编辑模式找到对应用户并更新 const index users.findIndex(u u.id id); if (index ! -1) { users[index] { id: parseInt(id), name, email, department: dept }; showSuccessToast(用户信息已更新); } } else { // 新增模式生成新 ID取当前最大 ID 1 const newId users.length ? Math.max(...users.map(u u.id)) 1 : 1; users.push({ id: newId, name, email, department: dept }); showSuccessToast(用户添加成功); } // 保存到 localStorage 并重绘 localStorage.setItem(users, JSON.stringify(users)); renderUserList(); // 关闭模态框 const modal bootstrap.Modal.getInstance($(#addModal)[0]); modal.hide(); $(#userForm)[0].reset(); $(#editId).val(); $(#userForm).removeClass(was-validated); });逻辑说明form.checkValidity()是原生 HTML5 表单验证方法返回布尔值form.classList.add(was-validated)强制显示所有验证提示。bootstrap.Modal.getInstance()是 Bootstrap 5 获取模态框实例的标准方式比$(#addModal).modal(hide)更可靠。showSuccessToast()是自定义提示函数见下文避免依赖第三方库。3. 实现编辑与删除功能jQuery 事件委托 Bootstrap 模态框复用3.1 编辑操作点击“编辑”按钮填充表单复用同一模态框编辑不是打开新窗口而是复用#addModal仅修改标题和按钮文字并预填当前行数据。关键点在于事件委托——因为表格行是动态生成的不能对.edit-btn直接绑定事件而要委托给父容器#userTableBody// 事件委托处理动态生成的编辑按钮 $(#userTableBody).on(click, .edit-btn, function() { const userId $(this).data(id); const user users.find(u u.id userId); if (user) { $(#addModalLabel).text(编辑用户); $(#editId).val(user.id); $(#nameInput).val(user.name); $(#emailInput).val(user.email); $(#deptInput).val(user.department || ); // 重置验证状态 $(#userForm).removeClass(was-validated); $(#nameInput, #emailInput).removeClass(is-invalid); $(.invalid-feedback).hide(); // 显示模态框 const modal new bootstrap.Modal($(#addModal)[0]); modal.show(); } });为什么用事件委托因为renderUserList()每次都会清空并重建tr直接$(.edit-btn).on(click, ...)绑定的事件监听器会丢失。委托给#userTableBody后无论tr如何重建只要点击目标符合.edit-btn选择器事件就会被正确捕获。3.2 删除确认用 Bootstrap Alert 替代原生 confirm提升体验原生confirm()弹窗样式丑陋且无法定制。本例用 Bootstrap 的alert组件构建轻量确认层覆盖在表格上方点击“确定”才真正删除// 删除确认层 DOM 结构初始隐藏 const deleteConfirmHtml div iddeleteConfirm classposition-fixed top-0 start-0 w-100 h-100 bg-black bg-opacity-25 d-flex align-items-center justify-content-center stylez-index: 1060; div classbg-white rounded p-4 shadow-sm stylemax-width: 400px; h5 classmb-3确认删除/h5 p classtext-muted mb-4此操作不可撤销将永久删除该用户。/p div classd-flex gap-2 button classbtn btn-secondary flex-grow-1 idcancelDelete取消/button button classbtn btn-danger flex-grow-1 idconfirmDelete确定删除/button /div /div /div; $(body).append(deleteConfirmHtml); // 事件委托处理删除按钮 $(#userTableBody).on(click, .delete-btn, function() { const userId $(this).data(id); window.currentDeleteId userId; // 临时存储待删 ID $(#deleteConfirm).show(); }); // 取消删除 $(#cancelDelete).on(click, function() { $(#deleteConfirm).hide(); }); // 确认删除 $(#confirmDelete).on(click, function() { const userId window.currentDeleteId; users users.filter(u u.id ! userId); localStorage.setItem(users, JSON.stringify(users)); renderUserList(); showSuccessToast(用户已删除); $(#deleteConfirm).hide(); });参数说明z-index: 1060是 Bootstrap Modal 的默认层级确保确认层盖在所有内容之上。window.currentDeleteId是最简方案存储上下文避免闭包或复杂状态管理。删除后立即调用renderUserList()保证表格行数与users.length严格同步。3.3 搜索功能jQuery 过滤数组 高亮关键词搜索不是发请求而是对users数组做客户端过滤。输入关键词后只渲染匹配的行并用mark标签高亮关键词$(#searchBtn, #searchInput).on(keyup, function(e) { if (e.key Enter || e.type click) { const keyword $(#searchInput).val().trim(); if (!keyword) { renderUserList(); // 清空搜索时显示全部 return; } const filtered users.filter(user user.name.includes(keyword) || user.email.includes(keyword) || (user.department user.department.includes(keyword)) ); // 重绘过滤结果 const tbody $(#userTableBody); tbody.empty(); filtered.forEach(user { const highlightedName highlightText(user.name, keyword); const highlightedEmail highlightText(user.email, keyword); const highlightedDept user.department ? highlightText(user.department, keyword) : -; const row tr>/* app.css */ .toast-container { position: fixed; top: 20px; right: 20px; z-index: 1050; max-width: 350px; } .toast { animation: slideInRight 0.3s ease-out, fadeOut 3s 2.7s forwards; } keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }// app.js function showSuccessToast(message) { const toastId toast- Date.now(); const toastHtml div id${toastId} classtoast-container div classtoast align-items-center text-white bg-success border-0 rolealert aria-liveassertive aria-atomictrue div classd-flex div classtoast-body${message}/div button typebutton classbtn-close btn-close-white me-2 m-auto>function setButtonLoading(btn, isLoading) { const $btn $(btn); if (isLoading) { $btn.prop(disabled, true).html( span classspinner-border spinner-border-sm rolestatus aria-hiddentrue/span span classms-2处理中.../span ); } else { $btn.prop(disabled, false).html(保存); } } // 在 saveUserBtn 点击事件开头调用 $(#saveUserBtn).on(click, function() { setButtonLoading(this, true); // 模拟异步操作如 AJAX setTimeout(() { // ... 保存逻辑 setButtonLoading(this, false); }, 800); });逻辑说明setTimeout模拟后端响应延迟实际项目中替换为$.ajax()或fetch()即可。Spinner 使用 Bootstrap 5 内置的spinner-border无需额外图标资源。4.3 键盘快捷键Enter 提交、Esc 关闭模态框提升专业感在模态框内按 Enter 直接保存按 Esc 关闭窗口// 模态框内 Enter 提交 $(#addModal).on(keypress, function(e) { if (e.key Enter $(e.target).closest(#userForm).length) { e.preventDefault(); $(#saveUserBtn).click(); } }); // Esc 关闭模态框Bootstrap 5 默认支持但显式声明更清晰 $(#addModal).on(keydown, function(e) { if (e.key Escape) { const modal bootstrap.Modal.getInstance(this); if (modal) modal.hide(); } });注意$(e.target).closest(#userForm)确保只在表单内按 Enter 才触发避免误触其他输入框。Bootstrap 5 的 Modal 默认监听 Esc此处显式写出是为了代码可读性和调试便利。5. 调试与边界处理排查常见 jQuery Bootstrap 混合开发问题5.1 jQuery 选择器失效的 3 个高频原因及修复方案现象原因修复方式$(.edit-btn).on(click, ...)不生效按钮是动态生成的绑定时 DOM 不存在改用事件委托$(#userTableBody).on(click, .edit-btn, ...)$(#nameInput).val()返回空字符串输入框被 Bootstrap 的form-control类包裹但 jQuery 仍可正常读取检查是否误用了text()用于span而非val()用于input$(#addModal).modal(show)报错modal is not a functionBootstrap 5 已移除 jQuery 插件必须用new bootstrap.Modal(...)替换为const modal new bootstrap.Modal($(#addModal)[0]); modal.show();提示Bootstrap 5 官方文档明确说明「No jQuery required」所有 JS 组件均提供纯 JS API。若坚持用 jQuery 包装需自行封装适配层否则易踩坑。本例中 Modal、Toast 均采用官方 JS API仅 DOM 操作和事件绑定使用 jQuery分工清晰。5.2 localStorage 数据损坏时的容错机制用户可能手动清空或篡改localStorage导致JSON.parse()报错。必须加 try-catch 并提供降级方案let users []; try { const stored localStorage.getItem(users); if (stored) { users JSON.parse(stored); // 验证数据结构 if (!Array.isArray(users) || !users.every(u typeof u.id number)) { throw new Error(Invalid data format); } } } catch (e) { console.warn(localStorage data corrupted, resetting to default, e); users [ { id: 1, name: 张三, email: zhangsanexample.com, department: 技术部 } ]; localStorage.setItem(users, JSON.stringify(users)); }参数说明typeof u.id number检查关键字段类型避免字符串 ID 导致后续filter()失效。console.warn记录日志便于排查生产环境可替换为 Sentry 上报。5.3 Bootstrap 表单验证的 2 个隐藏陷阱陷阱 1required属性对select无效若select的第一个option的value即使设了required选中它也不会触发验证。必须设置value为非空字符串或用:not([value])伪类判断。陷阱 2form-control类与width: 100%冲突Bootstrap 的form-control默认display: block且width: 100%若父容器宽度不足如col-sm-3输入框会溢出。解决方案给父容器加overflow: hidden或改用w-auto类。!-- 正确写法select 的第一个 option value 为空字符串但添加 required 后需额外 JS 校验 -- select classform-select iddeptInput required option value请选择部门/option option value技术部技术部/option /select script $(#deptInput).on(change, function() { if ($(this).val() ) { $(this).addClass(is-invalid); $(this).next(.invalid-feedback).show(); } else { $(this).removeClass(is-invalid); $(this).next(.invalid-feedback).hide(); } }); /script逻辑说明对select的required做手动校验因为浏览器原生验证对空value的处理不如input[typetext]严格。is-invalid类触发 Bootstrap 的红色边框和反馈提示与 input 保持视觉一致。本文还有配套的精品资源点击获取
返回列表