组件化的可编辑数据表格

设计了一个可编辑的表格,表格内容从JSON文件中获取并动态渲染。用户在表格中编辑单元格时,会进行输入验证,满足条件的修改会被保存,同时更新总分列。表格支持删除行功能,且修改会反映到原始数据集。此外,还实现了动画错误提示和便捷的操作体验。
摘要由CSDN通过智能技术生成

设计思路

实现方法

实现效果


设计思路

       设计可编辑数据表格,表格可编辑的内容部分单机可以生成一个输入框,并且自动获取输入框焦点。在输入框输入修改内容之后,判断输入框的内容是否满足表格输入条件;若不满足则弹出错误提示框提示用户重新输入内容,若满足则用户单击空白处即可对更改的内容进行修改和保存。其中表格的数据来自外部的json,通过json数据生成可编辑表格。根据实际情况,表格没有新增数据功能。表格的可编辑列,计算的列,每列的数据大小,以及是否删除都可进行配置,在修改单元格内容和删除行数据都会映射到相应数据集中。对数据修改和保存后,对应的表格的总分列也会通过重新计算在表格中更新并保存。

实现方法

写好基本样式和框架,并且把表格需要的数据写在json文件中,通过Ajax获取json中的数据

let ajax = new XMLHttpRequest();
ajax.open("get", "data2.json");
ajax.send();
ajax.onreadystatechange = function () {
  if (ajax.readyState == 4 && ajax.status == 200) {
    let alldata = JSON.parse(ajax.responseText);
    title_data.push(alldata.t_title);
    grade_data.push(alldata.t_grades);
    getHtml();
  }
};

定义getHTML方法,先取出每一行的数据,对于表格的表头,通过Object.values()直接取出数据,并通过模板字符串直接渲染到页面中。对于表格内容,通过Object.keys()获取每行数据的键名数组,先定义一个temp_grade并赋值<tr>,通过for in 获取下标并取出每一个键名,判断当前索引值是否等于键名数组的长度减一,若满足条件,则temp_grade加等于td并拼接上</tr>,反之,直接等于td。然后把temp_grade插入到HTML中。

function getHtml() {
  let titlekey, gradekey;
  for (item of title_data) {
    for (let i = 0; i < item.length; i++) {
      titlekey = Object.values(item[i]);
      let temp_title = `
                    <th>${titlekey}</th>
                   `;
      stutable_title.insertAdjacentHTML("beforeend", temp_title);
    }
  }
  for (item of grade_data) {
    for (let i = 0; i < item.length; i++) {
      gradekey = Object.keys(item[i]);
      let temp_grade = `<tr>`;
      for (let j in gradekey) {
        let k = gradekey[j];

        if (j == gradekey.length - 1) {
          temp_grade += `<td>${item[i][k]}</td></tr>`;
        } else {
          temp_grade += `<td>${item[i][k]}</td>`;
        }
      }
      stutable_grade.insertAdjacentHTML("beforeend", temp_grade);
    }
  }
  totalScoreBar();
  setAllScore([2, 3, 4, 5, 6, 7, 8]);
  setEditable([2, 3, 4, 5, 6, 7, 8]);
  updateScore();
  actionBar();
}

定义totalScoreBar方法用于在thead里添加总分这一列,并通过setAttribute给它设置rname属性值为allgrade。

function totalScoreBar() {
  let allscore = document.createElement("th");
  allscore.innerText = "总分";
  stutable_title.appendChild(allscore);
  for (let j = 0; j < stu_trs.length; j++) {
    let score = document.createElement("td");
    score.innerText = "0";
    stu_trs[j].appendChild(score);
    score.setAttribute("rname", "allgrade");
  }
}

定义actionBar方法用于在thead里添加操作栏这一列。并在每个tr里添加button标签。

function actionBar() {
  let caozuo = document.createElement("th");
  caozuo.innerText = "操作";
  stutable_title.appendChild(caozuo);
  for (let k = 0; k < stu_trs.length; k++) {
    let caozuo2 = document.createElement("td");
    let btn = document.createElement("button");
    btn.innerText = "删除";
    caozuo2.appendChild(btn);
    stu_trs[k].appendChild(caozuo2);
  }
  delRow();
}

定义setEditable方法,用于设置哪些可编辑。传入一个数组arr表示可编辑的单元格列。通过for循环先获取表格行和列,再通过arr.forEach()和setAttribute方法给arr元素表示的那一列单元格设置name为editable。

function setEditable(arr) {
  var strow = stutable.rows.length;
  for (let i = 1; i < strow; i++) {
    let stcell = stutable.rows[i].cells;
    arr.forEach(function (item) {
      stcell[item].setAttribute("name", "editable");
    });
  }
  setCellCilck();
}

定义setAllScore方法,用于设置哪些可以计算分数。传入一个数组arr表示可计算的单元格列。通过for循环先获取表格行和列,再通过arr.forEach()和setAttribute方法给arr元素表示的那一列单元格设置class为grade。


function setAllScore(arr) {
  var strow = stutable.rows.length;
  for (let i = 1; i < strow; i++) {
    let stcell = stutable.rows[i].cells;
    arr.forEach(function (item) {
      stcell[item].setAttribute("class", "grade");
    });
  }
}

定义一个updateScore方法,用来计算分数。通过class取出每行的分数的值,再取出总成绩的值。每个人总成绩等于每行分数相加。

function updateCell(ele, scorearr) {
  let scoreMax = scorearr[ele.cellIndex - 2];
  scoreMax = scoreMax || 100;
  console.log("当前科目的满分是:" + scoreMax);
  if (document.getElementsByClassName("active-input").length == 0) {
    var oldhtml = ele.innerHTML;
    ele.innerHTML = "";
    var newInput = document.createElement("input");
    newInput.setAttribute("class", "active-input");
    newInput.value = oldhtml;
    newInput.onblur = function () {
      this.value = parseFloat(this.value);
      if (this.value < 0 || this.value > scoreMax) {
        console.log("err");
        addAnimate();
        thetips.style.display = "block";
        return;
      } else {
        thetips.style.display = "none";
        ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;

        let ediId = ele.parentNode.children[0].innerHTML;
        for (item of grade_data) {
          for (let i = 0; i < item.length; i++) {
            let gradekey = Object.keys(item[i]);
            if (item[i].id == ediId) {
              item[i][gradekey[ele.cellIndex]] = parseFloat(this.value);
            }
          }
        }
        console.log("修改后的数据是:", grade_data);
        updateScore();
      }
    };
    newInput.select();
    ele.appendChild(newInput);
    newInput.focus();
  } else {
    return;
  }
}

定义一个addAnimate方法,表示单元格输入错误时的动画提示。

function addAnimate() {
  thetips.className = "err movedown";
}

定义一个delRow方法,用于表示删除单元格行操作。通过rowindex获取当前行,再定义一个delindex变量,把rowindex-1的值赋给它。然后通过deleteRow(rowindex)删除行。然后取出当前单元格所在行的id为ediId,遍历原始数据。然后取出的当前单元格对应的数据的下标,然后判断ediId是否等于原数组的id,若等于,则删除当前行的数据。

function delRow() {
  for (let i = 0; i < delbtns.length; i++) {
    delbtns[i].onclick = function () {
      let rowindex = this.parentNode.parentNode.rowIndex;
      let delindex = rowindex - 1;
      stutable.deleteRow(rowindex);
      let ediId = this.parentNode.parentNode.children[0].innerHTML;
      for (item of grade_data) {
        for (let i = 0; i < item.length; i++) {
          if (item[i].id == ediId) {
            item.splice(delindex, 1);
            console.log("删除后的数据是:", grade_data);
          }
        }
      }
    };
  }
}

定义setCellCilck方法,用于给class为grade的单元格添加点击事件。在里面定义一个scorearr数组,用于存放各科目的满分成绩。并将该数组传入到updateCell里面。


function setCellCilck() {
  let scorearr = [150, 150, 150, 100, 100, 100, 100];
  for (let i = 0; i < editcell.length; i++) {
    editcell[i].onclick = function () {
      updateCell(this, scorearr);
      delRow();
    };
  }
}

定义updateCell方法,用于更新单元格的内容。传入ele和定义好的scorearr,表示当前点击的单元格和各个科目满分的数组。先取出当前ele的cellIndex,获取对应的满分数据。然后获取旧的单元格数据并保存为oldhtml。然后创建一个input标签,并传入oldhtml。在input标签的聚焦事件中判断输入的input值是否合法,若不合法,则调用addAnimate方法,弹出error标签的错误提示信息,若合法,则保存当前的值。然后取出当前单元格所在行的id为ediId,遍历原始数据并通过Object.keys()取出键数组。然后取出的当前单元格所在行的列数,然后判断ediId是否等于原数组的id,若等于,则将新的值赋给它,从而实现原数组的修改。

function updateCell(ele, scorearr) {
  let scoreMax = scorearr[ele.cellIndex - 2];
  scoreMax = scoreMax || 100;
  console.log("当前科目的满分是:" + scoreMax);
  if (document.getElementsByClassName("active-input").length == 0) {
    var oldhtml = ele.innerHTML;
    ele.innerHTML = "";
    var newInput = document.createElement("input");
    newInput.setAttribute("class", "active-input");
    newInput.value = oldhtml;
    newInput.onblur = function () {
      this.value = parseFloat(this.value);
      if (this.value < 0 || this.value > scoreMax) {
        console.log("err");
        addAnimate();
        thetips.style.display = "block";
        return;
      } else {
        thetips.style.display = "none";
        ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;

        let ediId = ele.parentNode.children[0].innerHTML;
        for (item of grade_data) {
          for (let i = 0; i < item.length; i++) {
            let gradekey = Object.keys(item[i]);
            if (item[i].id == ediId) {
              item[i][gradekey[ele.cellIndex]] = parseFloat(this.value);
            }
          }
        }
        console.log("修改后的数据是:", grade_data);
        updateScore();
      }
    };
    newInput.select();
    ele.appendChild(newInput);
    newInput.focus();
  } else {
    return;
  }
}

实现效果

    对于页面开发不仅要实现基础的功能应用,还要实现更好更便捷的操作。页面的美观,用户的良好体验也至关重要,满足更好的性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
vben是一款基于Vue.js框架开发的前端组件库,提供了丰富的可视组件和工具,方便开发人员快速构建数据可视的网页应用。在vben中,大数据量可编辑表格可能会出现卡顿的情况。 首先,大数据量意味着表格中包含的数据量非常庞大,可能达到成千上万条记录。在渲染这么大量的数据时,就需要消耗较多的计算和内存资源。如果浏览器或设备的性能不够强大,就可能导致表格在进行数据更新和渲染时出现卡顿的现象。 其次,可编辑表格需要实时监听用户的操作,并及时更新表格中的数据。这个过程也需要进行数据的计算和更新,当数据量较大时,这个过程就会变得更加耗时,从而导致表格的卡顿。 为了解决这个问题,可以采取以下的优措施: 1. 数据分页加载:将大数据量分为多个页面进行加载,每次只加载当前页面所需的数据,这样可以降低渲染负担和提高数据更新的速度。 2. 虚拟滚动:只渲染当前可见的部分数据,随着用户滚动表格,再动态加载其他数据。这样可以减少DOM元素的数量,优性能。 3. 合理使用缓存:合理使用缓存机制,尽可能减少重复的计算和请求,提高数据的读取和更新效率。 4. 优算法和数据结构:通过优算法和数据结构,减少不必要的计算和数据操作,提高整体的性能。 总之,处理大数据量可编辑表格卡顿的问题需要综合考虑各种因素,包括数据量、设备性能、算法优等。通过合理的优措施,可以提升表格的更新和渲染效率,降低卡顿的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值