向上或向下移动 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');">↑</button>
<button onclick="upNdown('down');">↓</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');">↑</button>
<button onclick="upNdown('down');">↓</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');">↑</button>
<button onclick="upNdown('down');">↓</button>
【讨论】:
非常感谢您的回答。这就是我一直在寻找的。我没有足够的声誉来投票,但如果可以的话,我会的。再次感谢!以上是关于向上或向下移动 HTML 表格单元格(不是行)的主要内容,如果未能解决你的问题,请参考以下文章