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

时间:2012-06-10 06:03:20

标签: jquery html algorithm html-table

我有一个包含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>

5 个答案:

答案 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的代码,如果有两个相邻的行扫描,则会返回错误的结果。我需要解决这个问题。

以下是https://jsfiddle.net/goua3m13/

的示例

答案 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 Parserhttps://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;
}