我有一个包含ROWSPAN和COLSPAN的HTML表。
如何使用jQuery找到每个单元格的“可视位置”?
例如,这是我的表格的可视化表示,每个单元格填充了“视觉位置”算法应返回的内容:
(注意:我只关心<tbody>
中的单元格,列引用可以是整数,而不是字母字符,我只是这样做才能轻松突出问题) < / p>
+--+--+--+--+--+
| |A |B |C |D |
+--+--+--+--+--+
|1 |A1|B1 |D1|
+--+--+--+--+ +
|2 |A2 |C2| |
+--+ +--+ +
|3 | |C3| |
+--+--+--+--+--+
|4 |A4|B4|C4|D4|
+--+--+--+--+--+
|XYZ |
+--+--+--+--+--+
我已尝试实现第一个,但是单元格C3的引用是不准确的,因为它没有考虑ROWSPANS。第二个链接可以合并到第一个的解决方案中,但我无法弄清楚如何。
我希望将它用作名为getCellLocation(cell)
的函数,它将返回一个返回类似位置的关联数组:
function getCellLocation(cell)
{
var row_number = parseInt($(cell).parent().prevAll().length) + 1;
var col_number = 1;
$(cell).prevAll('td').each(function() {
col_number += $(this).attr('colspan') ? parseInt($(this).attr('colspan')) : 1;
});
var location = new Array();
location['row'] = row_number;
location['col'] = col_number;
location['index'] = $('td').index(cell) + 1;
return location;
}
$('table td').each(function(i){
var cell = getCellLocation($(this));
$(this).prepend('<span class="ref">R' + cell['row'] + ':C' + cell['col'] + ':D' + cell['index'] + '</span>');
});
以下是示例表的HTML:
<table border="1" cellspacing="0">
<thead>
<tr>
<th></th>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>A1</td>
<td colspan="2">B1</td>
<td rowspan="3">D1</td>
</tr>
<tr>
<th>2</th>
<td rowspan="2" colspan="2">A2</td>
<td>C2</td>
</tr>
<tr>
<th>3</th>
<td>C3</td>
</tr>
<tr>
<th>4</th>
<td>A4</td>
<td>B4</td>
<td>C4</td>
<td>D4</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">XYZ</td>
</tr>
</tfoot>
</table>
<style> span { background-color: #ffc; margin-right: .5em;} </style>
答案 0 :(得分:7)
这是我的解决方案:
function getCellLocation(cell) {
var cols = cell.closest("tr").children("td").index(cell);
var rows = cell.closest("tbody").children("tr").index(cell.closest("tr"));
var coltemp = cols;
var rowtemp = rows;
cell.prevAll("td").each(function() {
cols += ($(this).attr("colspan")) ? parseInt($(this).attr("colspan")) - 1 : 0;
});
cell.parent("tr").prevAll("tr").each(function() {
//get row index for search cells
var rowindex = cell.closest("tbody").children("tr").index($(this));
// assign the row to a variable for later use
var row = $(this);
row.children("td").each(function() {
// fetch all cells of this row
var colindex = row.children("td").index($(this));
//check if this cell comes before our cell
if (cell.offset().left > $(this).offset().left) {
// check if it has both rowspan and colspan, because the single ones are handled before
var colspn = parseInt($(this).attr("colspan"));
var rowspn = parseInt($(this).attr("rowspan"));
if (colspn && rowspn) {
if(rowindex + rowspn > rows)
cols += colspn;
}
if(rowspn && rowindex + rowspn > rows) cols +=1;
}
});
});
我正在检查同时具有colspan和rowspan的单元格,因为其余部分由此代码的前五行处理。如果细胞同时具有rowspan和colspan,那么它们应该影响除此细胞之外不低于OR的其他细胞,因此我需要搜索每个细胞的先前细胞以进行交互。
答案 1 :(得分:1)
your solution my proposed table design
+--+--+--+--+--+ +--+--+--+--+--+
| |A |B |C |D | | |A |B |C |D | length 5 vs 5
+--+--+--+--+--+ +--+--+--+--+--+
|1 |A1|B1 |D1| |1 |A1|B1|//|D1|
+--+--+--+--+ + +--+--+--+--+--+
|2 |A2 |C2| | |2 |A2|//|C2|//| length 3 vs 5
+--+ +--+ + +--+--+--+--+--+
|3 | |C3| | |3 |//|//|C3|//|
+--+--+--+--+--+ +--+--+--+--+--+
|4 |A4|B4|C4|D4| |4 |A4|B4|C4|D4|
+--+--+--+--+--+ +--+--+--+--+--+
|XYZ | |XY|//|//|//|//| length 1 vs 5
+--+--+--+--+--+ +--+--+--+--+--+
// cells labeled '//' above have this class
td.stuffing { display: none; }
你看到我在那里做了什么吗?
这是第三行,例如:
<tr>
<th>2</th>
<td rowspan="2" colspan="2">A2</td>
<td class="stuffing"></td>
<td>C2</td>
<td class="stuffing"></td>
</tr>
现在检索正确索引的函数非常简单。
function getCellLocation(cell) {
return {row:cell.parentNode.rowIndex, cell:cell.cellIndex}
}
<小时/> 这是奖金。如果您要访问一个隐藏的单元格,它将自动遍历正确的单元格,该区域跨越隐藏的单元格。
function getSmartCell(table, row, col) {
var cell = table.rows[row].cells[col];
if (cell.className.indexOf("stuffing") == -1) return cell;
// traverse Left
while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) {
cell = table.rows[row].cells[--col];
}
// roll back one cell if no colSpan is found
if (cell.colSpan == 1) cell = table.rows[row].cells[++col];
// traverse Up
while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) {
cell = table.rows[--row].cells[col];
}
return cell;
}
用法:
var tb = document.querySelector("table");
getCellLocation(getSmartCell(tb,3,2)); // {row: 2, cell: 1}
<强>注意强>
我刚检查了getSmartCell
的代码,如果有两个相邻的行扫描,则会返回错误的结果。我需要解决这个问题。
答案 2 :(得分:0)
对于这种特定的布局(即如果你的第一行没有colspan和更多或更少的统一单元格边框)你可以这样做:
function getCellLocation(cell)
{
var row_number = cell.parentNode.rowIndex;
var col_number = "";
$(cell).parents('table').find('tr:first th').each( function()
{
if (cell.offsetLeft >= this.offsetLeft)
{
col_number = $(this).text();
}
else return false;
});
return col_number + row_number;
}
如果您希望数字列将其更改为
var col_number = 0;
...
if (cell.offsetLeft >= this.offsetLeft)
{
col_number++;
}
答案 3 :(得分:0)
这是一个能够处理复杂表结构的jQuery解决方案。此解决方案使用此处提供的Open Source WxT Table Parser:https://raw.github.com/wet-boew/wet-boew/master/src/js/dependencies/parserTable.js
您可以在Table Usability Concept Github Repository中找到相关文档。使用“Table Parser - WET 3.0发行版”下的API文档。
使用HTML表格标记和数据单元格(td)与标题单元格之间的视觉关系(th)完成表格解析
// Used to get the reference to the WxT table parser
var _pe = window.pe || {
fn : {}
};
// For each table elements
$('table').each(function () {
var $tbl = $(this);
// Parse the table
_pe.fn.parsertable.parse($tbl);
// For each data cell
$('td', $tbl).each(function () {
var $td = $(this),
tblparser;
// Get the API structure as defined under "Table Parser - WET 3.0 release" (https://github.com/duboisp/Table-Usability-Concept/blob/master/API/td.md#table-parser---wet-30-release)
tblparser = $td.data().tblparser;
// Set the cell location (x, y)
$td.html(tblparser.row.rowpos + ', ' + tblparser.col.start);
});
});
您可以在此处找到一个有效的示例:http://jsfiddle.net/TVttA/
干杯
: - )
答案 4 :(得分:0)
由于接受的答案缺少return
语句,并且仅适用于tbody和td(不适用于thead和th),因此我做了一些细微调整以使其起作用:
function getCellLocation(cell) {
var cols = cell.closest("tr").children("th, td").index(cell);
var rows = cell.closest("thead, tbody").children("tr").index(cell.closest("tr"));
cell.prevAll("th, td").each(function() {
cols += ($(this).attr("colspan")) ? parseInt($(this).attr("colspan")) - 1 : 0;
});
cell.parent("tr").prevAll("tr").each(function() {
//get row index for search cells
var rowindex = cell.closest("thead, tbody").children("tr").index($(this));
// assign the row to a variable for later use
var row = $(this);
row.children("th, td").each(function() {
//check if this cell comes before our cell
if (cell.offset().left > $(this).offset().left) {
// check if it has both rowspan and colspan, because the single ones are handled before
var colspn = parseInt($(this).attr("colspan"));
var rowspn = parseInt($(this).attr("rowspan"));
if (rowspn && rowindex + rowspn > rows) {
cols += colspn ? colspn : 1;
}
}
});
});
return cols;
}