自动将 <th> 的基于数据标签的内容附加到相应的 <td> 以实现响应式 table 视图
Automatically append data-labels based content of <th> to corresponding <td> for responsive table view
我需要根据相应 th
的内容自动将 data-*
标签附加到 td
。所以,结果应该是这样的:
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Heading 1">table cell content</td>
<td data-label="Heading 2">table cell content</td>
<td data-label="Heading 3">table cell content</td>
<td data-label="Heading 4">table cell content</td>
<td data-label="Heading 5">table cell content</td>
</tr>
</tbody>
</table>
虽然有许多 jQuery 解决方案,但我需要用 vanilla JavaScript
来完成
有关代表性 jQuery 解决方案,请参阅:
1.
Pull th content into a td data-label attribute
我很想使用 element.cellIndex
的解决方案,但似乎无法实现。
我做过各种错误的尝试。
这是我最近一次失败的尝试:
function addMobileTableData() {
var table = document.querySelector('.table');
var th = table.querySelectorAll('th');
var td = table.querySelectorAll('td');
var tdCollection = Array.from(td);
var thCollection = Array.from(th);
var thCount = th.length;
tdCollection.forEach(function(tdItem, index){
for (index = 0; index < thCount; index++) {
var headerLabel = thCollection[index].innerHTML;
console.log(headerLabel);
tdItem.setAttribute('data-th', headerLabel[index]);
};
});
};
这显然是不正确的。它为每个 td
分配一个 data-th
标签,但仅将最后一个字符串中的第一个字符附加到每个 td
。
如果您赶时间,我们将不胜感激。对我做错了什么的解释会很好。一个完整的工作解决方案是 Fan-Freaking-Tastic。
但是,我会尽我所能。
谢谢。
其实你们很亲近。原来你访问的是你返回的 Header 标签的字符串,因此只返回第一个字符。额外的循环也是不必要的。下面的工作代码片段:
function addMobileTableData() {
var table = document.querySelector('.table');
var bodyTrCollection = table.querySelectorAll('tbody tr');
var th = table.querySelectorAll('th');
var thCollection = Array.from(th);
for (var i = 0; i < bodyTrCollection.length; i++) {
var td = bodyTrCollection[i].querySelectorAll('td');
var tdCollection = Array.from(td);
for (var j = 0; j < tdCollection.length; j++) {
if (j === thCollection.length) {
continue;
}
var headerLabel = thCollection[j].innerHTML;
tdCollection[j].setAttribute('data-th', headerLabel);
}
}
};
addMobileTableData();
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
</tbody>
</table>
编辑:添加了一个额外的检查来说明当 th 和 tds 的数量不匹配时的情况。
第二次编辑:函数分解为多行。我现在已经修正了这个错误。
更简洁的版本可以是:
const table = document.querySelector('table.table');
const headerCells = table.querySelectorAll('thead th');
headerCells.forEach((_headerCell, i) => {
table
.querySelectorAll(`tbody tr td:nth-child(${i + 1})`)
.forEach((cell) => {
cell.dataset.label = headerCells[i].innerText.trim();
});
});
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
</tr>
</tbody>
</table>
我需要根据相应 th
的内容自动将 data-*
标签附加到 td
。所以,结果应该是这样的:
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Heading 1">table cell content</td>
<td data-label="Heading 2">table cell content</td>
<td data-label="Heading 3">table cell content</td>
<td data-label="Heading 4">table cell content</td>
<td data-label="Heading 5">table cell content</td>
</tr>
</tbody>
</table>
虽然有许多 jQuery 解决方案,但我需要用 vanilla JavaScript
来完成有关代表性 jQuery 解决方案,请参阅:
1.
Pull th content into a td data-label attribute
我很想使用 element.cellIndex
的解决方案,但似乎无法实现。
我做过各种错误的尝试。
这是我最近一次失败的尝试:
function addMobileTableData() {
var table = document.querySelector('.table');
var th = table.querySelectorAll('th');
var td = table.querySelectorAll('td');
var tdCollection = Array.from(td);
var thCollection = Array.from(th);
var thCount = th.length;
tdCollection.forEach(function(tdItem, index){
for (index = 0; index < thCount; index++) {
var headerLabel = thCollection[index].innerHTML;
console.log(headerLabel);
tdItem.setAttribute('data-th', headerLabel[index]);
};
});
};
这显然是不正确的。它为每个 td
分配一个 data-th
标签,但仅将最后一个字符串中的第一个字符附加到每个 td
。
如果您赶时间,我们将不胜感激。对我做错了什么的解释会很好。一个完整的工作解决方案是 Fan-Freaking-Tastic。
但是,我会尽我所能。
谢谢。
其实你们很亲近。原来你访问的是你返回的 Header 标签的字符串,因此只返回第一个字符。额外的循环也是不必要的。下面的工作代码片段:
function addMobileTableData() {
var table = document.querySelector('.table');
var bodyTrCollection = table.querySelectorAll('tbody tr');
var th = table.querySelectorAll('th');
var thCollection = Array.from(th);
for (var i = 0; i < bodyTrCollection.length; i++) {
var td = bodyTrCollection[i].querySelectorAll('td');
var tdCollection = Array.from(td);
for (var j = 0; j < tdCollection.length; j++) {
if (j === thCollection.length) {
continue;
}
var headerLabel = thCollection[j].innerHTML;
tdCollection[j].setAttribute('data-th', headerLabel);
}
}
};
addMobileTableData();
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
<tr>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
<td>table cell content</td>
</tr>
</tbody>
</table>
编辑:添加了一个额外的检查来说明当 th 和 tds 的数量不匹配时的情况。
第二次编辑:函数分解为多行。我现在已经修正了这个错误。
更简洁的版本可以是:
const table = document.querySelector('table.table');
const headerCells = table.querySelectorAll('thead th');
headerCells.forEach((_headerCell, i) => {
table
.querySelectorAll(`tbody tr td:nth-child(${i + 1})`)
.forEach((cell) => {
cell.dataset.label = headerCells[i].innerText.trim();
});
});
<table class="table">
<thead class="bg-gray-100">
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
<td>cell content</td>
</tr>
</tbody>
</table>