11

我有一个包含 ROWSPAN 和 COLSPAN 的 HTML 表。

如何使用 jQuery 找到每个单元格的“视觉位置”?

例如,这是我的表格的可视化表示,每个单元格都填充了“视觉位置”算法应返回的内容:(
注意:我只关心其中的单元格<tbody>,列引用可以是整数,而不是字母字符,我这样做只是为了轻松突出问题)

+--+--+--+--+--+
|  |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>
4

5 回答 5

10

这是我的解决方案:

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 的单元格,因为其余部分由该代码的前五行处理。如果单元格同时具有行跨度和跨度,它们应该会影响不低于或除此单元格之外的其他单元格,因此我需要搜索每个单元格的先前单元格以进行交互。

于 2012-06-10T08:57:50.377 回答
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如果有两个相邻的行跨度,它会返回错误的结果。我需要解决这个问题。

这是一个示例https://jsfiddle.net/goua3m13/

于 2015-05-21T15:38:31.390 回答
0

这是一个能够处理复杂表结构的 jQuery 解决方案。此解决方案使用此处提供的开源 WxT 表解析器https ://raw.github.com/wet-boew/wet-boew/master/src/js/dependencies/parserTable.js

您将在Table Usability Concept Github 存储库中找到文档。使用“Table Parser - WET 3.0 release”下的 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/

干杯

:-)

于 2012-11-16T18:23:53.433 回答
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++;
}
于 2012-06-10T07:56:08.517 回答
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;
}
于 2020-07-08T17:22:19.337 回答