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

如何使用jQuery将CRUD表格数据存储到Local Storage

jQuery CRUD表格接入LocalStorage持久化实现

现有CRUD交互逻辑已经完整,只需要补充数据读写能力,在数据变更时同步到LocalStorage、页面加载时读取缓存渲染即可,不需要改动原有核心操作逻辑。

核心实现逻辑

  • 封装通用存储方法:提取表格中已保存的有效行数据,序列化为JSON字符串存入LocalStorage
  • 封装通用加载方法:页面初始化时读取LocalStorage中的缓存数据,反序列化后渲染为表格行
  • 在所有会改动已保存数据的操作节点(新增保存、编辑更新、删除数据)完成后,触发存储方法同步数据
  • 未保存的新增/编辑临时行不做存储,刷新页面后自动清除,符合常规交互逻辑

修改后完整可运行代码

<!DOCTYPE html>
<html lang="en">
<head>
    <title>CRUD Table jQuery</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
    <div class="container">
        <div class="row"> 
            <div class="col-md-12 text-right">
                <input type="button" id="btnAdd" class="btn btn-primary para" value="Add New" />
            </div>
        </div>
        <div class="row pt-3">
            <div class="col-md-12 col-sm-12 col-12 p-2 ">
                <table id="tblData" class="table table-bordered table-hover table-striped">
                    <thead>
                        <tr> 
                            <th>ID</th>
                            <th>Name</th>
                            <th>Address</th>
                            <th>Age</th>
                            <th class="tdaction">Action</th>
                        </tr>
                    </thead>
                    <tbody> 
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    <script>
        const STORAGE_KEY = 'crudTableData';
        var emptyRow = "<tr><td colspan='5' class='text-center'>暂无数据</td></tr>";
        var emptyNewRow = "<tr class='trNewRow'>"; 
        emptyNewRow = emptyNewRow + "    <td class='tdID'>";
        emptyNewRow = emptyNewRow + "        <input type='text' class='form-control txtID' />";
        emptyNewRow = emptyNewRow + "    </td>";
        emptyNewRow = emptyNewRow + "    <td class='tdName'>";
        emptyNewRow = emptyNewRow + "        <input type='text' class='form-control txtName' />";
        emptyNewRow = emptyNewRow + "    </td>";
        emptyNewRow = emptyNewRow + "    <td class='tdAddress'>";
        emptyNewRow = emptyNewRow + "        <input type='text' class='form-control txtAddress' />";
        emptyNewRow = emptyNewRow + "    </td>";
        emptyNewRow = emptyNewRow + "    <td class='tdAge'>";
        emptyNewRow = emptyNewRow + "        <input type='text' class='form-control txtAge' />";
        emptyNewRow = emptyNewRow + "    </td>";
        emptyNewRow = emptyNewRow + "    <td class='tdAction'>";
        emptyNewRow = emptyNewRow + "        <button class='btn btn-sm btn-success btn-save'> Save</button>";
        emptyNewRow = emptyNewRow + "        <button class='btn btn-sm btn-secondary btn-cancel'> Cancel</button>";
        emptyNewRow = emptyNewRow + "    </td>";
        emptyNewRow = emptyNewRow + "</tr>";

        var rowButtons ="<button class='btn btn-success btn-sm btn-edit' > Edit </button>  <button class='btn btn-danger btn-sm btn-delete' > Delete </button>";
        var rowUpdateButtons ="<button class='btn btn-success btn-sm btn-save' > Update </button>  <button class='btn btn-danger btn-sm btn-delete' > Delete </button> ";

        // 保存表格数据到LocalStorage
        function saveTableToStorage() {
            const dataList = [];
            $('#tblData tbody tr').each(function() {
                // 跳过空提示行、未保存的新增/编辑临时行
                if ($(this).find('.txtID').length > 0 || $(this).find('td[colspan]').length > 0) {
                    return;
                }
                dataList.push({
                    id: $(this).find('.tdID').text().trim(),
                    name: $(this).find('.tdName').text().trim(),
                    address: $(this).find('.tdAddress').text().trim(),
                    age: $(this).find('.tdAge').text().trim()
                })
            })
            localStorage.setItem(STORAGE_KEY, JSON.stringify(dataList));
        }

        // 从LocalStorage加载数据渲染表格
        function loadTableFromStorage() {
            const storageData = localStorage.getItem(STORAGE_KEY);
            const $tbody = $('#tblData tbody');
            $tbody.html('');
            if (!storageData) {
                $tbody.append(emptyRow);
                return;
            }
            const dataList = JSON.parse(storageData);
            if (dataList.length === 0) {
                $tbody.append(emptyRow);
                return;
            }
            dataList.forEach(item => {
                const row = `<tr>
                    <td class="tdID">${item.id}</td>
                    <td class="tdName">${item.name}</td>
                    <td class="tdAddress">${item.address}</td>
                    <td class="tdAge">${item.age}</td>
                    <td class="tdAction">${rowButtons}</td>
                </tr>`;
                $tbody.append(row);
            })
        }

        $(document).ready(function () {
            // 页面加载优先读取缓存数据
            loadTableFromStorage();
            
            $("#btnAdd").click(function () { 
                if ($("#tblData tbody").find('td[colspan]').length > 0) {
                    $("#tblData tbody").html("");
                }
                $("#tblData tbody").append(emptyNewRow);
            });
            
            $('#tblData').on('click', '.btn-save', function () {
                const id =  $(this).parent().parent().find(".txtID").val();
                $(this).parent().parent().find(".tdID").html(""+id+"");
                const name =  $(this).parent().parent().find(".txtName").val();
                $(this).parent().parent().find(".tdName").html(""+name+""); 
                const address =  $(this).parent().parent().find(".txtAddress").val();
                $(this).parent().parent().find(".tdAddress").html(""+address+"");
                const age =  $(this).parent().parent().find(".txtAge").val();
                $(this).parent().parent().find(".tdAge").html(""+age+"");
                $(this).parent().parent().find(".tdAction").html(rowButtons);
                // 保存后同步数据到LocalStorage
                saveTableToStorage();
            });
             
            
            $('#tblData').on('click', '.btn-delete', function () { 
                $(this).parent().parent().remove();
                if ($("#tblData tbody tr").length == 0) {
                    $("#tblData tbody").append(emptyRow);
                }
                // 删除后同步数据到LocalStorage
                saveTableToStorage();
            });
            

            $('#tblData').on('click', '.btn-cancel', function () { 
                $(this).parent().parent().remove();
                if ($("#tblData tbody tr").length == 0) {
                    loadTableFromStorage();
                }
            });


            $('#tblData').on('click', '.btn-edit', function () { 

                const id =$(this).parent().parent().find(".tdID").html();
                $(this).parent().parent().find(".tdID").html("<input type='text' value='"+id+"' class='form-control txtID' />"); 

                const name =$(this).parent().parent().find(".tdName").html();
                $(this).parent().parent().find(".tdName").html("<input type='text' value='"+name+"' class='form-control txtName' />"); 

                const address =$(this).parent().parent().find(".tdAddress").html();
                $(this).parent().parent().find(".tdAddress").html("<input type='text' value='"+address+"' class='form-control txtAddress' />"); 

                const age =$(this).parent().parent().find(".tdAge").html();
                $(this).parent().parent().find(".tdAge").html("<input type='text' value='"+age+"' class='form-control txtAge' />"); 

                $(this).parent().parent().find(".tdAction").html(rowUpdateButtons);
                               
            });

        });
    </script> 
</body> 
</html>

补充说明

  • 修正了原逻辑中空行colspan为4的问题,实际表格共5列,空行提示可占满整行宽度
  • 原新增行的取消按钮文案误写为Delete,已修正为Cancel,避免和删除按钮混淆
  • 给删除按钮单独添加了btn-delete类,避免和其他按钮的事件绑定冲突
  • LocalStorage存储键名可通过修改STORAGE_KEY常量自定义,数据以标准JSON格式存储,可直接在浏览器开发者工具的Application面板查看、修改

内容的提问来源于stack exchange,提问作者Nirantharika Selvachandran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:18:14