<table id="editableTable">
  <tr>
    <th colspan="3">可编辑单元格的表格</th>
  </tr>
  <tr>
    <td class="nw"><strong>Northwest</strong>
      <br>Metal
      <br>Silver
      <br>Elders
    </td>
    <td class="n"><strong>North</strong>
      <br>Water
      <br>Blue
      <br>Change
    </td>
    <td class="ne"><strong>Northeast</strong>
      <br>Earth
      <br>Yellow
      <br>Direction
    </td>
  </tr>
  <tr>
    <td class="w"><strong>West</strong>
      <br>Metal
      <br>Gold
      <br>Youth
    </td>
    <td class="c"><strong>Center</strong>
      <br>All
      <br>Purple
      <br>Harmony
    </td>
    <td class="e"><strong>East</strong>
      <br>Wood
      <br>Blue
      <br>Future
    </td>
  </tr>
  <tr>
    <td class="sw"><strong>Southwest</strong>
      <br>Earth
      <br>Brown
      <br>Tranquility
    </td>
    <td class="s"><strong>South</strong>
      <br>Fire
      <br>Orange
      <br>Fame
    </td>
    <td class="se"><strong>Southeast</strong>
      <br>Wood
      <br>Green
      <br>Romance
    </td>
  </tr>

</table>
<div id="editControl" hidden>
  <button class="edit-ok">确定</button>
  <button class="edit-cancel">取消</button>
</div>
table {
  width: 100%;
  table-layout: fixed;
  /*自动列宽*/
  border-spacing: 5px;
}

td {
  vertical-align: middle;
  background-color: antiquewhite;
  padding: 10px;
  text-align: center;
  text-overflow: clip;
}

td:nth-child(2n + 2) {
  background-color: #ff0;
}

#editControl {
  text-align: center;
  position: absolute;
  margin: 0px;
  right: 0px;
  bottom: -25px;
  z-index: 1;
}

.edit {
  border: 1px solid skyblue;
  margin: 0px;
  padding: 2px;
  display: block;
  resize: none;
  outline: none;
  overflow: auto;
  position: absolute;
  top: 0px;
  left: 0px;
  box-sizing: border-box;
}

.edit-td {
  position: relative;
}
let edit = document.createElement("textarea");
edit.className = "edit";
edit.addEventListener("keyup", (e) => {
  console.log(e.key);
  if (e.key == "Escape") clickBtnCancel();
});

let currentTD;
editableTable.addEventListener("click", function (e) {
  if (e.target.tagName == "TD") clickTD(e.target);
  else if (e.target.tagName == "BUTTON" && e.target.className == "edit-ok")
    clickBtnOK();
  else if (e.target.tagName == "BUTTON" && e.target.className == "edit-cancel")
    clickBtnCancel();
});

function clickTD(td) {
  if (currentTD) {
    reset();
  }
  currentTD = td;
  edit.value = td.innerHTML;
  edit.style.width = td.offsetWidth + "px";
  edit.style.height = td.clientHeight + "px";
  td.classList.add("edit-td");
  td.append(edit);
  td.append(editControl);
  editControl.hidden = false;
  edit.style.display = "block";
  edit.focus();
  //set value
}
function clickBtnOK() {
  reset();
}
function clickBtnCancel(td) {
  reset(false);
}
function reset(ok = true) {
  if (!currentTD) return;
  currentTD.classList.remove("edit-td");
  edit.hidden = true;
  edit.style.display = "none";
  editControl.hidden = true;
  document.body.append(edit, editControl);
  if (ok) currentTD.innerHTML = edit.value;
  currentTD = null;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.