【问题标题】:How to get a cell's location如何获取单元格的位置
【发布时间】:2010-10-14 06:53:30
【问题描述】:

我正在编写一个管理一个非常大的表的脚本。当用户单击表格单元格时,我想知道他们单击了哪个单元格。 例如

--------------
|     |      |
|     | Click|
--------------

应该给我一个单元格引用 (1, 1)。

我可以用javascript做到这一点。它运行的页面将 jquery 用于其他目的,因此任何基于 jquery 的解决方案都很好。

编辑:为了澄清,左上角的单元格是 (0, 0)。出于性能原因,事件需要绑定到 table,而不是 tds。

【问题讨论】:

  • 您的“点击”看起来像是在单元格 1,0 或 0,1 或 1,2 或 2,1...
  • 当你说你想知道“他们点击了哪个单元格”时,你真的是指实际坐标还是对那个元素的引用?
  • 出于好奇,什么数量级是“非常大”
  • 我需要实际的坐标。非常大 = 200 x 200。0,0 是左上角。抱歉没有具体说明。
  • 我的代码表现如何?

标签: javascript jquery


【解决方案1】:

遍历 DOM 层次结构...

您应该能够通过获取对单击的 TD 的 DOM 节点的引用来执行此操作,然后向后走 previousSibling 链直到到达第一列,边走边算。

如果您位于同级链的开头(即行中的第一个 TD),parentNode 应该是 TR 节点,并且您可以执行类似的遍历 previousSibling TR 到计算行数。

..或用附加属性标记每个单元格

或者,当您创建表格时,为每个单元格添加一些虚假的 rowidx="??"colidx="??" 属性并使用 @ 检索这些属性987654324@。如果要使用合法属性,可以将行和列索引放在axis="??,??" 属性中。

【讨论】:

  • +1,我得到了你的支持 :) 有人通过并否决了所有人。
【解决方案2】:

使用event 对象的target 属性很容易做到这一点:

$('#mytable').click(function(e) {
    var tr = $(e.target).parent('tr');
    var x = $('tr', this).index(tr);
    var y = tr.children('td').index($(e.target));
    alert(x + ',' + y);
});

这种方法只允许您将 1 个事件处理程序绑定到整个表格,然后确定单击了哪个表格单元格。这被称为事件委托,在适当的情况下效率更高,这符合要求。使用它可以避免将事件绑定到每个<td>,并且它不需要硬编码坐标。因此,如果您的表格如下所示:

<table id='mytable'>
    <tr>
      <td>hi</td>
      <td>heya</td>
    </tr>
    <tr>
      <td>boo</td>
      <td>weee</td>
    </tr>
</table>

它会在点击时提醒坐标。你可以用它做任何事情。 :)

如果您发现性能太慢(取决于您的表有多大),那么您将不得不诉诸硬编码或两者的组合,可能只对&lt;tr&gt; 索引进行硬编码,因为那将是最慢的获取,然后动态获取&lt;td&gt; 索引。最后,如果所有这些坐标业务完全没有必要,而您真正想要的是对点击的&lt;td&gt; 的引用,那么您只需这样做:

$('#mytable').click(function(e) {
    var td = $(e.target);
    // go crazy
});

【讨论】:

    【解决方案3】:
    $('td').click(function(event) {
      var row = $(this).parent('tr');
      var horizontal = $(this).siblings().andSelf().index(this);
      var vertical = row.siblings().andSelf().index(row);
      alert(horizontal+','+vertical);
    });
    

    【讨论】:

    • 这将绑定一个事件处理程序到每个 td。他说他有一张大桌子。最好是绑定到表本身然后弄清楚。
    • 可能是这样,为了简单起见,我只是将 td 扔在那里。恕我直言,这些答案的目的是向提问者提出总体思路,而不是提供现成的即插即用解决方案:)
    • 最初的尝试,在 tds 上使用了事件处理程序。性能非常糟糕。
    【解决方案4】:

    您提到了一个非常大的表格 - 将点击绑定到每个 td 是不明智的。更好的方法是使用 .live 方法,如果您仍在 jquery 1.2.6 上,您可以将点击事件绑定到表并使用事件委托。如果您需要此问题的代码。

    $("#tableId td").live('click', function () {
         var $this = $(this);
         var x = $this.prevAll().length;
         var y = $this.parent().prevAll.length;
         console.log(x + ", " + y);
    });
    

    【讨论】:

      【解决方案5】:

      假设你的第一行第一列是 0,0

      var row = 0;
          $('#tblImages > tbody > tr').each( function(){
                     var col = 0;
      
                     $(this).children('td').each( function(){
      
                         $(this).attr("currentRow", row).attr("currentCol", col);
                         col++;
                     });
                     row++;
              }
              );
          $('#tblImages > tbody > tr > td').click(function(){
              alert( $(this).attr("currentRow") + "   " + $(this).attr("currentCol")); 
      

      这当然可以进一步改进..但它的工作原理

      【讨论】:

        【解决方案6】:

        window.onload = function () {
          document.getElementsByTagName('table')[0].addEventListener('click', function(element) {
            var rowIndex = element.target.parentElement.rowIndex;
            var cellIndex = element.target.cellIndex;
            
            document.getElementById('alert').innerHTML = ('Row index = ' + rowIndex + ', Column index = ' + cellIndex);
         }, false);
        }
        tr, th, td {
          padding: 0.6rem;
          border: 1px solid black
        }
        
        table:hover {
          cursor: pointer;
        }
        <table>
            <tbody>
                <tr>
                    <td>1</td>
                    <td>2</td>
                    <td>3</td>
                </tr>
        
                <tr>
                    <td>4</td>
                    <td>5</td>
                    <td>6</td>
                </tr>
            </tbody>
        </table>
        <p id="alert"></p>

        【讨论】:

          猜你喜欢
          • 2011-06-27
          • 1970-01-01
          • 2013-06-07
          • 2017-10-10
          • 2020-08-18
          • 2011-10-01
          • 2012-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多