昨天晚上有个女生叫我帮他看一下前端怎么通过 JQuery 向后台发送数据,今天上午刚测试完Java,下午就花了一点时间来实现动态表格案例,其实也不难,就是使用原生的JS来实现;其中有一个很奇葩的需求。他们老师说第一次访问页面时不展示数据,之后第二次访问页面的时候才向后端发送请求渲染表格数据,实现思路:在LocalStorage 存储一个首次展示的一个flag,页面加载前就获取LocalStorage中的值,判断是否需要展示数据。
成果展示:
MOCK_DATA = [ {id: 1, name: "技术部", sn: 'KFB'}, {id: 2, name: "生产部", sn: 'SCB'}, {id: 3, name: "测试部", sn: 'CSB'}, {id: 4, name: "研发部", sn: 'YFB'}, {id: 5, name: "总经办", sn: 'CEO'} ];
修改 MOCK_DATA 中的数据之后的运行截图:
MOCK_DATA = [ {id: 1, name: "技术部", sn: 'KFB', hobby: "篮球"}, {id: 2, name: "生产部", sn: 'SCB', hobby: "泡妞"}, {id: 3, name: "测试部", sn: 'CSB', hobby: "打代码"}, {id: 4, name: "研发部", sn: 'YFB', hobby: "学Java"}, {id: 5, name: "总经办", sn: 'CEO', hobby: "睡觉"} ];
写了一点简单的样式,直接使用就行
*{ padding:0; margin:0; } table{ width:500px; margin:100px auto; border-collapse:collapse;/*边框合并模式*/ text-align:center; } table caption { font-size: 24px; font-weight: 700; } td,th{ border:1px solid #333; } td a:hover { color: blue; cursor: pointer; } tr:nth-child(2) { height:40px; background-color: #cccccc; } button { position: absolute; top: 100px; right: 300px; }
封装的工具方法
``/** 创建一个指定名称的元素并返回 */ function createElement(name) { return document.createElement(name); } /** * 将指定的元素节点追加到指定的父节点上 * * parentNode 父节点 * currentNode 当前节点 */ function append(parentNode, currentNode) { parentNode.append(currentNode); } /** 通过 id 获取元素节点并返回 */ function $(id) { return document.getElementById(id); }
创建按钮。绑定点击事件实现清除缓存的功能,清除成功之后刷新页面
function clearCache() { let clearBtn = createElement("button"); clearBtn.setAttribute("id", "clearBtn"); clearBtn.innerText = "清除缓存"; append(document.body, clearBtn); $('clearBtn').onclick = () => { if (! localStorage.getItem("once")) { alert("当前没有缓存要清理!"); } else { const ret = confirm("确定要清除缓存吗?"); if (ret) { // 清除缓存 localStorage.clear(); // 刷新页面 location.reload(); } } } }
核心代码;MOCK_DATA 是前端模拟的数据,可以是向后台发送请求得到后台响应的数据;通过 createElement方法创建 table、caption、tr、th、td等元素节点,通过 append方法将指定的元素节点挂在追加到指定的节点上;table 的表头是通过 Object.getOwnPropertyNames(Obj) 方法动态获取,防止硬编码问题;表格中的内容就通过遍历从后台拿到的数据渲染到表格中
function init_table() { let MOCK_DATA = null; // 判断是否是首次展示页面,如果是首次渲染页面向 localStorage 中存放一个首次展示的状态 // 并提示用户首次打开页面不展示数据 // 如果不是首次打开页面则向后台发请求获取数据,展示表格数组 if (!localStorage.getItem("once")) { alert("页面首次展示不展示数据! ") localStorage.setItem("once","yes"); return; } else { MOCK_DATA = [ {id: 1, name: "技术部", sn: 'KFB'}, {id: 2, name: "生产部", sn: 'SCB'}, {id: 3, name: "测试部", sn: 'CSB'}, {id: 4, name: "研发部", sn: 'YFB'}, {id: 5, name: "总经办", sn: 'CEO'} ]; // TODO 向后台发送请求,获取列表数据并赋值给 MOCK_DATA } // 创建节点 table、caption、tr、td let table = createElement("table"); let caption = createElement("caption"); var tr = createElement("tr"); // 设置表格标题 caption.innerText = "部门列表"; append(table, caption); // 拿取模拟数据的第一个对象,获取对象里面的属性名,用于设置表格表头 let t_heads = Object.getOwnPropertyNames(MOCK_DATA[0]); for (let i = 0; i < t_heads.length; i++) { var th = createElement("th"); th.innerText = t_heads[i]; append(tr, th); } // 创建操作的表头 let fun_th = createElement("th"); fun_th.innerText = "操作"; append(tr, fun_th); append(table, tr); MOCK_DATA.forEach(data => { var tr = createElement("tr"); // 设置当前行 id tr.setAttribute("id", `tr_${data.id}`) for(property in data) { var td = createElement("td"); td.innerText = data[property]; if ('id' == property) { td.setAttribute("id", `${data.id}`); } append(tr, td); } /************ 创建每一列的操作节点,并设置相属性 **************/ var fun_td = createElement("td"); // 创建编辑节点 var aEdit = createElement("a"); // 创建删除节点 var aDelete = createElement("a"); aEdit.innerText = "编辑 "; aDelete.innerText = " 删除"; aEdit.onclick = () => { // 通过 id 获取元素,拿到元素的值并强转为数字类型 var data_id = Number($(`${data.id}`).innerText); // TODO 在这里发送编辑的请求 alert(`${data_id} 向后台发送编辑请求`); } aDelete.onclick = () => { // 通过 id 获取元素,拿到元素的值并强转为数字类型 var data_id = Number($(`${data.id}`).innerText); // TODO 在这里向后端发送删除的请求,并刷新页面 alert(`${data_id} 向后台发送编删除请求`); // 删除子节点 table.removeChild($(`tr_${data.id}`)); } append(fun_td, aEdit); append(fun_td, aDelete); append(tr, fun_td); /************ end **************/ // 将创建的 tr 行节点添加到 table 表格节点上 append(table, tr); }) // 将创建的表格节点挂在到 body / <body></body> 节点上 append(document.body, table); clearCache(); }
最后调用初始化方法,
// 初始化表格 init_table();
由于时间关系,后台代码就没有实现,数据全由前端模拟的 MOCK_DATA 数据,代码还需要优化,有点冗余