向上或向下移动 HTML Table 个单元格(不是行)
Move HTML Table Cell up or down (not row)
我正在做一个项目,其中有一个 HTML table,我需要为用户提供交换两个 HTML table 单元格内容的选项。
具体来说,用户可以单击 select 一行,然后选择将该行向上或向下移动。实际上,他们只是在移动代表信息的第 2 列的内容。第 1 列表示顺序,不会改变。
table 总共有两列。
第 1 列将代表线性顺序(即 1-10),它不会改变。
第 2 列将是数据库提供的信息(在示例代码中我提供了姓氏)。
我制作了两个按钮,向上和向下,并使用了两个 Javascript 功能,允许用户 select 一行并将其向上或向下移动。
当前代码成功将整行向上或向下移动,但是我只需要第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>
这完全取决于您想要什么。您提到曾尝试移动 innerHTML,因此此代码段会这样做 - 保留两个 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 来交换内容(即所有属性也将被移动)。但是,这可能不是您想要的,因为例如,如果这是排行榜,顶部元素上可能有一个内联样式,它以金色突出显示它。这完全取决于您的要求。
另请注意,该代码段假定 table 格式正确,因为在 selectable 行中没有非 td 元素作为直接子元素。
为了简单起见(至少在表面上),此答案对发布的代码进行了更改,并防止使用按钮将 header 行向下移动到 table:
保留对所选行的引用而不是索引。
在HTML中,header行被放置在thead
元素中,数据行在tbody
元素中(重要在代码中)。
移动一行时,两行的顺序会颠倒,然后它们第一个单元格的 textContent
交换 - 无需将“顺序”列单元格移动到不同的行。如果这太简单了,您可以交换单元格的 innerHTML
属性。
在进行更改时,再次单击一行可取消选择它:单击 table 外部将是您可以监控的另一件事,如您所愿。
"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 table,我需要为用户提供交换两个 HTML table 单元格内容的选项。
具体来说,用户可以单击 select 一行,然后选择将该行向上或向下移动。实际上,他们只是在移动代表信息的第 2 列的内容。第 1 列表示顺序,不会改变。
table 总共有两列。 第 1 列将代表线性顺序(即 1-10),它不会改变。 第 2 列将是数据库提供的信息(在示例代码中我提供了姓氏)。
我制作了两个按钮,向上和向下,并使用了两个 Javascript 功能,允许用户 select 一行并将其向上或向下移动。
当前代码成功将整行向上或向下移动,但是我只需要第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>
这完全取决于您想要什么。您提到曾尝试移动 innerHTML,因此此代码段会这样做 - 保留两个 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 来交换内容(即所有属性也将被移动)。但是,这可能不是您想要的,因为例如,如果这是排行榜,顶部元素上可能有一个内联样式,它以金色突出显示它。这完全取决于您的要求。
另请注意,该代码段假定 table 格式正确,因为在 selectable 行中没有非 td 元素作为直接子元素。
为了简单起见(至少在表面上),此答案对发布的代码进行了更改,并防止使用按钮将 header 行向下移动到 table:
保留对所选行的引用而不是索引。
在HTML中,header行被放置在
thead
元素中,数据行在tbody
元素中(重要在代码中)。移动一行时,两行的顺序会颠倒,然后它们第一个单元格的
textContent
交换 - 无需将“顺序”列单元格移动到不同的行。如果这太简单了,您可以交换单元格的innerHTML
属性。在进行更改时,再次单击一行可取消选择它:单击 table 外部将是您可以监控的另一件事,如您所愿。
"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>