5

我希望能够按行和列索引选择表格单元格,同时补偿rowspancolspan。例如,在下表中,

示例表

我希望将(1,2)红色,(2,3)绿色和(3,3)蓝色着色,以产生:

预期表

我尝试了“按行号和列号选择表格中的任意单元格”这个问题的答案,但这产生了:

实际表

这是 jsFiddle:http://jsfiddle.net/acheong87/27HuN/

我明白发生了什么,我什至发现了另一个问题,“Table cellIndex and rowIndex with colspan/rowspan”,答案是作为插件提供的,但似乎没有更简单的方法!毕竟,实际结果的着色似乎可以理解,但不直观,而预期结果的着色似乎更直观,更容易掌握。

谁能想到一个聪明而简单的方法来实现这个?


更新

这是我(糟糕的)尝试的新 jsFiddle,以防它可能激发其他人的新想法。基本上,如果我们假设 row 和 col 标题没有跨越(当然,这不是一个有效的假设),那么我们可以使用偏移量来“定位”正确的单元格:

function getCell(table, r, c)
{
    var rowHead = $(table.rows[r].cells[0]);
    var colHead = $(table.rows[0].cells[c]);
    var y = rowHead.offset().top + rowHead.outerHeight(true)/2;
    var x = colHead.offset().left + colHead.outerWidth(true)/2;
    return $(document.elementFromPoint(x, y));
}

虽然演示似乎有效,但存在许多问题:

  1. 不能假设没有跨越行和列标题。
  2. 如果行或列的中点不在视口之外,则不起作用;elementFromPoint似乎取决于视口。
  3. 滚动、边距等起作用时不能可靠地工作;一般脆弱;宁愿不依赖坐标数学。
4

3 回答 3

3

这是一种不同的“预处理”方法:

var grid = (function(){

  var table = $("#table")[0], a=[], cell, i, j, k, l, y;

  for (i=0;i<table.rows.length;i++) a[i] = [];

  for (i=0;i<table.rows.length;i++) {
      y = 0;
      for (j=0;j<table.rows[i].cells.length;j++) {
          while (a[i][j + y]) y++;
          cell = $(table.rows[i].cells[j]);
          xspan = parseInt(cell.attr('rowspan') || 1);
          yspan = parseInt(cell.attr('colspan') || 1);
          for (k=0;k<xspan;k++) {
              for (l=0;l<yspan;l++) {
                  if(i + k < table.rows.length) a[i + k][j + y + l] = [i,j];
              }
          }
      }
  }

  return a;

})();

colorCell(1,2,'red');
colorCell(2,3,'green');
colorCell(3,3,'blue');

function colorCell(i,j,s){
    var a = grid[i][j];
    $(table.rows[a[0]].cells[a[1]]).css('background-color', s);
}

jsfiddle

于 2012-12-27T21:26:59.117 回答
1

您的设计是定制的,因此您的解决方案也必须是定制的。由于表格与预期结构的偏离程度,没有简单的通用方法来解决此问题。删除注释掉的td元素,您将看到脚本正在处理的真实形状。

与所有良好的优化一样,您应该预先做一些工作。当你准备它们时,使用类名或数据属性来标记哪个单元格,之后的工作将大大减少。从昂贵的计算和解决方法(例如建议的插件)中可以看出,预先不做任何工作最终会让您付出代价。

有关我的意思的示例,请参见此 jsfiddle:http: //jsfiddle.net/27HuN/2/

万一发生什么事,这里是一个副本

html

<table id="table" border="1" cellpadding="10" style="text-align:center;">
<tbody>
    <tr class="0">
        <td class="0-0">(0,0)</td>
        <td class="0-1">(0,1)</td>
        <td class="0-2">(0,2)</td>
        <td class="0-3">(0,3)</td>
    </tr>
    <tr class="1">
        <td class="1-0">(1,0)</td>
        <td colspan="2" class="1-1 1-2">(1,1) (1,2)</td>
        <!--<td></td>-->
        <td rowspan="2" class="1-3 2-3">(1,3)<br/>(2,3)</td>
    </tr>
    <tr class="2">
        <td class="2-0">(2,0)</td>
        <td class="2-1">(2,1)</td>
        <td class="2-2">(2,2)</td>
        <!--<td></td>-->
    </tr>
    <tr class="3">
        <td class="3-0">(3,0)</td>
        <td class="3-1">(3,1)</td>
        <td class="3-2">(3,2)</td>
        <td class="3-3">(3,3)</td>
    </tr>
</tbody>
</table>​

js

$('.1-2').css('background-color', 'red');
$('.2-3').css('background-color', 'green');
$('.3-3').css('background-color', 'blue');

请注意,这是一个简单的示例,您可能希望使用不仅仅是数字的类名。也许r0c0r2c3标记的类型,或者更详细的逻辑来表示这些位置。

于 2012-12-27T19:06:26.203 回答
1

我已经在 J​​SFiddle 中尝试过......虽然花了一些时间......

var table = $("#table")[0];

SetColumnColor(1, 2, 'red');
SetColumnColor(2, 3, 'green');
SetColumnColor(3, 3, 'blue');

function SetColumnColor(rowIndex, cellIndex, color){

    var actualRowIndex = GetActualRowIndex(table, rowIndex, cellIndex);
    var actualCellIndex = GetActualCellIndex(table.rows[actualRowIndex], cellIndex);
    $(table.rows[actualRowIndex].cells[actualCellIndex]).css('background-color', color);
}

function GetActualCellIndex(row, cellIndex) {
    var actualCellIndex = cellIndex;
    $(row.cells).each(function(index) {
        var colSpan = parseInt($(this).attr('colspan'));
        if(colSpan != NaN && colSpan > 0)
        {
            //alert(colSpan);
            actualCellIndex = actualCellIndex - colSpan + 1;
        }
    });

    return actualCellIndex;
}

function GetActualRowIndex(table, rowIndex, cellIndex) {
    var actualRowIndex = rowIndex;

    if(table.rows[rowIndex].cells[cellIndex] != null)
        return rowIndex;

    $(table.rows).each(function(index) {
        if(rowIndex <= index)
            return actualRowIndex;
        var realCellIndex = GetActualCellIndex(this, cellIndex);
        //alert("Row:" + index + "(" + realCellIndex + "," + cellIndex+ ")");
        var rowSpan = parseInt($(table.rows[index].cells[realCellIndex]).attr('rowspan'));
        if(rowSpan != NaN && rowSpan > 0)
        {
            //alert(rowSpan + "(" + index + "," + realCellIndex + ")");
            actualRowIndex = actualRowIndex - rowSpan + 1;
        }
    });

    return actualRowIndex;
}

在此处获得工作演示

于 2012-12-27T20:10:40.847 回答