如何找到每个表格单元格';s";“视觉定位”;使用jQuery?
我有一个包含行跨度和列跨度的HTML表 如何使用jQuery查找每个单元格的“可视位置” 例如,这里是我的表的可视化表示,每个单元格填充了“可视化位置”算法应该返回的内容:如何找到每个表格单元格';s";“视觉定位”;使用jQuery?,jquery,html,algorithm,html-table,Jquery,Html,Algorithm,Html Table,我有一个包含行跨度和列跨度的HTML表 如何使用jQuery查找每个单元格的“可视位置” 例如,这里是我的表的可视化表示,每个单元格填充了“可视化位置”算法应该返回的内容: (注意:我只关心中的单元格,列引用可以是整数,而不是字母字符,我这样做只是为了容易地突出问题) 我已经尝试实现了第一个,但是单元格C3的引用不准确,因为它没有考虑行跨度。第二个链接可能可以合并到第一个链接的解决方案中,但我不知道如何合并 我希望将其用作名为getCellLocation(cell)的函数,该函数将返回
(注意:我只关心
中的单元格,列引用可以是整数,而不是字母字符,我这样做只是为了容易地突出问题)
我已经尝试实现了第一个,但是单元格C3的引用不准确,因为它没有考虑行跨度。第二个链接可能可以合并到第一个链接的解决方案中,但我不知道如何合并
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>');
});
函数getCellLocation(单元格)
{
var row_number=parseInt($(cell.parent().prevAll().length)+1;
变量col_数=1;
$(单元格).prevAll('td')。每个(函数(){
col_number+=$(this.attr('colspan')?parseInt($(this.attr('colspan')):1;
});
var location=新数组();
位置['row']=行号;
位置['col']=col_编号;
位置['index']=$('td')。索引(单元格)+1;
返回位置;
}
$('table td')。每个(函数(i){
var cell=getCellLocation($(this));
$(this).prepend('R'+单元格['row']+':C'+单元格['col']+':D'+单元格['index']+');
});
下面是示例表的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>
A.
B
C
D
1.
A1
地下一层
D1
2.
A2
C2
3.
C3
4.
A4
B4
补体第四成份
D4
XYZ
span{背景色:#ffc;右边距:.5em;}
对于此特定布局(即,如果第一行没有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++;
}
以下是我的解决方案:
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,则它们应该影响不在该单元格下方或旁边的其他单元格,因此我需要搜索每个单元格以前的单元格以进行交互。这里是一个能够处理复杂表结构的jQuery解决方案。此解决方案使用此处提供的: 您可以在中找到文档。使用“TableParser-WET 3.0发行版”下的API文档 通过使用HTML表格标记和数据单元格(td)和标题单元格(th)之间的可视关系来完成表解析 您可以在这里找到一个工作示例: 干杯 :-)
您的解决方案我建议的表格设计
+--+--+--+--+--+ +--+--+--+--+--+
|| A | B | C | D | A | B | C | D |长度5对5
+--+--+--+--+--+ +--+--+--+--+--+
|1 | A1 | B1 | D1 | 1 | A1 | B1 |/| D1|
+--+--+--+--+ + +--+--+--+--+--+
|2 | A2 | C2 | | | | 2 | A2 |/| C2 |/|长度3对5
+--+ +--+ + +--+--+--+--+--+
|3 | | C3 | | | 3 |/|/|/| C3|//|
+--+--+--+--+--+ +--+--+--+--+--+
|4 | A4 | B4 | C4 | D4 | 4 | A4 | B4 | C4 | D4|
+--+--+--+--+--+ +--+--+--+--+--+
|XYZ | | XY |/|/|/|/|/|/|/|/|长度1 vs 5
+--+--+--+--+--+ +--+--+--+--+--+
你看到我在那里做了什么吗
这是第三行,例如:
<tr>
<th>2</th>
<td rowspan="2" colspan="2">A2</td>
<td class="stuffing"></td>
<td>C2</td>
<td class="stuffing"></td>
</tr>
这是奖金。如果要访问一个隐藏的单元格,它将自动遍历到正确的单元格,该单元格将跨越那些隐藏的单元格
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
的代码,如果有两个相邻的行间距,它将返回错误的结果。我需要解决这个问题
以下是一个示例,因为接受的答案缺少一个
返回
语句,并且只适用于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;
}
在某些情况下,似乎存在轻微问题或重复计算。考虑到应用于这个表时的结果(参见CysCal3-RoO2):如果表预期更宽,则仍然有一些古怪的东西。看这里:(Row2Col9,Row2Col12,Row5Col9,Row5Col12)好的,我尝试了另一种方法。这更可靠,因为它使用单元的偏移位置来计算先前的交互。这是:。我会更新代码。@tpaksu您有更新脚本吗?在这种情况下,它不起作用。我更新了我的代码。添加了一行:
if(rowspn&&rowsindex+rowspn>行)cols+=1代码>。您可以在这里进行测试:在我的问题中,有一个经过深思熟虑的原因,为什么“合并”的单元格跨越列和行。对于用例,它需要这样,不能使用空白单元格和隐藏them@Turgs您仍然可以使用列间距和行间距,同时也可以使用隐藏单元格。
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}
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;
}