向上或向下移动 HTML 表格单元格(不是行)

Posted

技术标签:

【中文标题】向上或向下移动 HTML 表格单元格(不是行)【英文标题】:Move HTML Table Cell up or down (not row) 【发布时间】:2021-10-09 05:38:52 【问题描述】:

我正在做一个项目,我有一个 html 表格,我需要为用户提供交换两个 HTML 表格单元格内容的选项。

具体来说,用户可以单击以选择一行,然后选择向上或向下移动该行。实际上,他们只是在移动代表信息的第 2 列的内容。第 1 列代表顺序,它不会改变。

该表总共有两列。 第 1 列将代表线性顺序(即 1-10),它不会改变。 第 2 列将是数据库提供的信息(在我提供姓氏的示例代码中)。

我构建了两个按钮,向上和向下,并使用了两个 javascript 函数,允许用户选择一行并将其向上或向下移动。

当前代码成功移动一整行上下移动,但是我只需要第2列的单元格内容上下移动

请查看提供的代码和 JSFiddle 并告诉我如何解决这个问题?提前致谢!

var index; // variable to set the selected row index
function getSelectedRow() 
  var table = document.getElementById("table");
  for (var i = 1; i < table.rows.length; i++) 
    table.rows[i].onclick = function() 
      // clear the selected from the previous selected row
      // the first time index is undefined
      if (typeof index !== "undefined") 
        table.rows[index].classList.toggle("selected");
      

      index = this.rowIndex;
      this.classList.toggle("selected");

    ;
  


getSelectedRow();

function upNdown(direction) 
  var rows = document.getElementById("table").rows,
    parent = rows[index].parentNode;

  if (direction === "up") 
    if (index > 1) 
      parent.insertBefore(rows[index], rows[index - 1]);
      // when the rowgo up the index will be equal to index - 1
      index--;
    
  

  if (direction === "down") 
    if (index < rows.length - 1) 
      parent.insertBefore(rows[index + 1], rows[index]);
      // when the row go down the index will be equal to index + 1
      index++;
    
  
tr 
  cursor: pointer


.selected 
  background-color: red;
  color: #fff;
  font-weight: bold


button 
  margin-top: 10px;
  background-color: #eee;
  border: 2px solid #00F;
  color: #17bb1c;
  font-weight: bold;
  font-size: 25px;
  cursor: pointer
<!DOCTYPE html>
<html lang="en">

  <head>

    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
    <meta content="30" http-equiv="refresh">

    <title> .Title </title>

    <style>
      .bd-placeholder-img 
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
      

      @media (min-width: 768px) 
        .bd-placeholder-img-lg 
          font-size: 3.5rem;
        
      

    </style>


  </head>

  <body>

    <header>

    </header>



    <main>


      <table id="table" border="1">
        <tr>
          <th>Order</th>
          <th>Last Name</th>
        </tr>
        <tr>
          <td>1</td>
          <td>Smith</td>
        </tr>
        <tr>
          <td>2</td>
          <td>Johnson</td>
        </tr>
        <tr>
          <td>3</td>
          <td>Roberts</td>
        </tr>
        <tr>
          <td>4</td>
          <td>Davis</td>
        </tr>
        <tr>
          <td>5</td>
          <td>Doe</td>
        </tr>
      </table>
      <button onclick="upNdown('up');">&ShortUpArrow;</button>
      <button onclick="upNdown('down');">&ShortDownArrow;</button>


    </main>
    <!-- Bootstrap core JavaScript -->
    <script src="/vendor/jquery/jquery.min.js"></script>
    <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
    <script src="/js/sidebar.js"></script>
  </body>

</html>

Link to JSFiddle

【问题讨论】:

所以你的意思是像这样工作,考虑到第 4 行和第 5 行有 2 个项目。您只需要交换第二列值。 (第一列是线性顺序,比如行号等),对吧? 我没有看过你的代码,但这个问题让我想知道,你能不能把 contents 复制到一个新的单元格,而不是尝试“移动一个单元格” ? @AbinThaha 是的,第 1 列本质上将按行号顺序排列。我只需要更改第 2 列的内容。感谢您的快速回复。 @wazz 是的,我愿意复制内容,并且我研究过 InnerHTML,但我无法使用它来抓取第 2 列。注意:我不知道我有多少行。因此,例如,我不能简单地交换 id=td1 和 id=td2 的内容。 【参考方案1】:

这完全取决于您想要什么。您提到曾尝试移动 innerHTML,所以这个 sn-p 会这样做 - 保留两个 tds 上的任何属性不移动(请参阅下面的注释):

var index; // variable to set the selected row index
function getSelectedRow() 
  var table = document.getElementById("table");
  for (var i = 1; i < table.rows.length; i++) 
    table.rows[i].onclick = function() 
      // clear the selected from the previous selected row
      // the first time index is undefined
      if (typeof index !== "undefined") 
        table.rows[index].classList.toggle("selected");
      

      index = this.rowIndex;
      this.classList.toggle("selected");

    ;
  


getSelectedRow();

function upNdown(direction) 
  var rows = document.getElementById("table").rows,
    parent = rows[index].parentNode;

  if (direction === "up") 
    if (index > 1) 
      // get the relevant cell which is the second one as we know only tds are the children
      let td = rows[index].children[1];
      let tdAbove = rows[index - 1].children[1];
      let temp = td.innerHTML;
      td.innerHTML = tdAbove.innerHTML;
      tdAbove.innerHTML = temp;
      // when the rowgo up the index will be equal to index - 1
      index--;
    
  

  if (direction === "down") 
    if (index < rows.length - 1) 
      let td = rows[index].children[1];
      let tdBelow = rows[index + 1].children[1];
      let temp = td.innerHTML;
      td.innerHTML = tdBelow.innerHTML;
      tdBelow.innerHTML = temp;
      // when the row go down the index will be equal to index + 1
      index++;
    
  
.bd-placeholder-img 
  font-size: 1.125rem;
  text-anchor: middle;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;


@media (min-width: 768px) 
  .bd-placeholder-img-lg 
    font-size: 3.5rem;
  


tr 
  cursor: pointer


.selected 
  background-color: red;
  color: #fff;
  font-weight: bold


button 
  margin-top: 10px;
  background-color: #eee;
  border: 2px solid #00F;
  color: #17bb1c;
  font-weight: bold;
  font-size: 25px;
  cursor: pointer
<body>

  <header>

  </header>



  <main>


    <table id="table" border="1">
      <tr>
        <th>Order</th>
        <th>Last Name</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Smith</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Johnson</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Roberts</td>
      </tr>
      <tr>
        <td>4</td>
        <td>Davis</td>
      </tr>
      <tr>
        <td>5</td>
        <td>Doe</td>
      </tr>
    </table>
    <button onclick="upNdown('up');">&ShortUpArrow;</button>
    <button onclick="upNdown('down');">&ShortDownArrow;</button>


  </main>

注意:在问题中引入了移动整个元素的想法,而不仅仅是其内容。您可以这样做,而不是通过使用例如 outerHTML 来交换内容(即所有属性也会被移动)。但是,这可能不是您想要的,因为例如顶部元素上可能有一个内联样式,如果这是一个排行榜,它会以金色突出显示。这完全取决于您的要求。

另请注意,sn-p 假定表格格式正确,因为在可选择的行中没有非 td 元素作为直接子元素。

【讨论】:

【参考方案2】:

这个答案为了简单起见(至少在表面上)更改了发布的代码,并防止使用按钮将标题行向下移动:

保存对选定行的引用而不是索引。

在 HTML 中,标题行放在 thead 元素中,数据行放在 tbody 元素中(在代码中很重要)。

移动一行时,两行的顺序颠倒,然后它们的第一个单元格的textContent 交换 - 没有将“顺序”列单元格移动到不同的行。如果这太简单了,您可以替换单元格的 innerHTML 属性。

在进行更改时,第二次单击一行用于取消选择它:单击表格外部将是您可以监控的另一件事,如您所愿。

"use strict";
const tbody = document.querySelector("#table tbody");
let selected = null;
tbody.addEventListener("click", function(e)
  let row = e.target.closest("tr");
  if( row === selected) 
    row.classList.toggle("selected")
    selected = null;
  
  else 
    if(selected) 
      selected.classList.toggle("selected");
    
    selected = row;
    row.classList.toggle("selected");
  
);

function upNdown( direction) 
  let up, down;
  if( selected) 
    up  =  direction == "up" ? selected : selected.nextElementSibling;
    down = direction == "up" ? selected.previousElementSibling : selected;
    if( up && down) 
      tbody.insertBefore(up, down); // put up before down
      var temp = up.firstElementChild.textContent; // swap first cells' text content
      up.firstElementChild.textContent = down.firstElementChild.textContent;
      down.firstElementChild.textContent = temp;
    
  
tr 
  cursor: pointer


.selected 
  background-color: red;
  color: #fff;
  font-weight: bold
<table id="table" border="1">
  <thead>
    <tr>
      <th>Order</th>
      <th>Last Name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Smith</td>
    </tr>
  
    <tr>
      <td>2</td>
      <td>Johnson</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Roberts</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Davis</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Doe</td>
    </tr>
   </tbody>
</table>
<button onclick="upNdown('up');">&ShortUpArrow;</button>
<button onclick="upNdown('down');">&ShortDownArrow;</button>

【讨论】:

非常感谢您的回答。这就是我一直在寻找的。我没有足够的声誉来投票,但如果可以的话,我会的。再次感谢!

以上是关于向上或向下移动 HTML 表格单元格(不是行)的主要内容,如果未能解决你的问题,请参考以下文章

向上滚动 uitablviewcell 部分可见

html表格中按啥键移动到上一个单元格

当您向上或向下滚动时,选择一个 UITableViewCell 会选择同一位置的其他单元格

在具有不同单元格高度的列表视图中滚动

TableView - 单元格的上移和下移功能

DataGrid 用鼠标拖动改变列宽,怎么做