可编辑表格

发布时间 2023-04-11 23:40:17作者: 饺子jo


设计思路

  1. 先通过 CSS+HTML 绘制基础表格样式及布局

  2. 根据题意:只能修改成绩数据的单元格,给相应 td 设置 name 属性,总分则单独设置 rname 属性,在 js 文件中获取所有需要修改的元素,通过 for 循环遍历给需要修改的单元格添加点击事件。

  3. 通过点击单元格来更新数据,更新数据需要通过使用 DOMAPI 添加 input 元素来传入新数据。

  4. 当输入值后根据 if 语句来判断输入值是否符合规定,如果错误则调用错误输入的动画,成功则更新总成绩。

  5. 更新总成绩通过 DOM 属性来获取每个学生的每门成绩,以及每个学生的总成绩。

  6. js 文件中包含获取 html 元素代码,给可编辑单元格添加点击事件,更新单元格,更新总成绩,错误动画。

实现方法

  • 在 JS 中通过 getElemByName,getElemByTagName 以及 CSS 选择器 querySelectorAll,parentNode 来获取节点(元素)
  • creatElement 创建节点,setAttribute 来设置节点属性
  • innerHTML 来改变 HTML 元素文本值

核心代码

html

    <div id="tableBox">
        <h2 class="title">可编辑表格</h2>
        <div class="err">成绩输入有误,请重新输入!</div>
        <table class="table">
            <thead>
                <tr>
                    <th>学号</th>
                    <th>姓名</th>
                    <th>语文</th>
                    <th>数学</th>
                    <th>英语</th>
                    <th>总分</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>1101</td>
                    <td>小王</td>
                    <td name="grade">98</td>
                    <td name="grade">80</td>
                    <td name="grade">91</td>
                    <td rname="allgrade">269</td>
                </tr>
                <tr>
                    <td>1102</td>
                    <td>小曾</td>
                    <td name="grade">88</td>
                    <td name="grade">87</td>
                    <td name="grade">92</td>
                    <td rname="allgrade">267</td>
                </tr>
                <tr>
                    <td>1103</td>
                    <td>小赵</td>
                    <td name="grade">75</td>
                    <td name="grade">90</td>
                    <td name="grade">86</td>
                    <td rname="allgrade">251</td>
                </tr>
                <tr>
                    <td>1104</td>
                    <td>小周</td>
                    <td name="grade">65</td>
                    <td name="grade">81</td>
                    <td name="grade">83</td>
                    <td rname="allgrade">229</td>
                </tr>
            </tbody>
        </table>
    </div>

js

//获取HTML中的元素
var grades = document.getElementsByName("grade");
var thetips = document.getElementsByClassName("err")[0];
var trs = document.getElementsByTagName("tr");
// 给单元格添加点击事件
function setCellCilck() {
  for (let i = 0; i < grades.length; i++) {
    grades[i].onclick = function () {
      updateCell(this);
    };
  }
}
setCellCilck();
// 更新单元格内容
function updateCell(ele) {
  if (document.getElementsByClassName("active-input").length == 0) {
    var oldhtml = ele.innerHTML;
    ele.innerHTML = "";
    // 通过DOM API 创建input元素,设置属性,值,方法
    var newInput = document.createElement("input");
    newInput.setAttribute("class", "active-input");
    newInput.value = oldhtml;
    newInput.onblur = function () {
      if (!Number(this.value) || this.value > 100 || this.value < 0) {
        console.log("err");
        addAnimate();
        thetips.style.display = "block";
        return;
      } else {
        thetips.style.display = "none";
        ele.innerHTML = this.value == oldhtml ? oldhtml : this.value;
        updateScore();
      }
    };
    newInput.select();
    ele.appendChild(newInput);
    newInput.focus();
  } else {
    return;
  }
}
// 更新总成绩
// 通过DOM属性来更新总成绩
function updateScore() {
  for (let n = 1; n < trs.length; n++) {
    var grade01 =
      grades[n].parentNode.parentNode.children[n - 1].querySelectorAll(
        "td[name]"
      );
    var grade02 =
      grades[n].parentNode.parentNode.children[n - 1].querySelectorAll(
        "td[rname]"
      );
    var sum = 0;
    for (let i = 0; i < grade01.length; i++) {
      sum += parseFloat(grade01[i].innerHTML);
      for (let j = 0; j < grade02.length; j++) {
        grade02[j].innerHTML = sum;
      }
    }
  }
}
updateScore();
function addAnimate() {
  thetips.className = "err movedown";
}

css

<!-- 错误动画 -->
.err {
  display: none;
  top: 95px;
  width: 160px;
  position: absolute;
  margin-left: -100px;
  left: 50%;
  text-align: center;
  padding: 15px 18px;
  background: rgb(255, 0, 0);
  border-radius: 5px;
  font-size: 13px;
  font-weight: 600;
  transition: top 1s;
  z-index: -1;
}

.movedown {
  top: 95px;
  animation: movedown 3s;
}

@keyframes movedown {
  0% {
    top: 95px;
  }

  50% {
    top: 48px;
  }

  100% {
    top: 95px;
  }
}