原生JS实现任意数据的动态表格

昨天晚上有个女生叫我帮他看一下前端怎么通过 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方法创建 tablecaptiontrthtd等元素节点,通过 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 数据,代码还需要优化,有点冗余

猜你喜欢

转载自blog.csdn.net/weixin_49137820/article/details/128025621
今日推荐