通过拖动选择表格中的单元格

44

我看了这个问题,看到了关于iPhone游戏的参考,你可以在屏幕上拖动选择字母。

我很想看到一个使用表格的Javascript实现。所以当你拖动鼠标经过每个单元格时,它们就会变成高亮状态。

我不确定最好的方法是什么,但我希望有人能尝试一下。有人在这里尝试过,但它并没有真正起作用。

alt text alt text

感谢Cacoo提供的性感图表。它就像一个在线的Visio,非常棒。去看看吧;)


1
有趣的挑战(和图表)。关键是要防止浏览器中的默认文本选择... - tbeseda
3个回答

92

这是一个可行的原型:http://jsfiddle.net/few5E/ 使用 jQuery 进行 DOM 钩子,但也可以很容易地使用其他框架实现。

更新: http://jsfiddle.net/Brv6J/ - 略微不同的版本,高亮状态仅在松开鼠标并再次单击时更改。

更新2: http://jsfiddle.net/Brv6J/3/ - 绑定 onselectstart 以防止在 IE 中选择文本。

一些相关事实:

  • 表格单元格的 mousedown 事件被挂钩以跟踪实际点击。此事件被停止,以阻止文本选择。还为相同效果绑定了 ontextselect 事件以兼容 IE。
  • mouseover 事件将切换单元格的高亮类。
  • mouseout 事件被钩在文档上。这是为了确保它始终运行。如果 mouseup 事件挂钩在表格单元格上,当你用鼠标在表格外面释放鼠标键时,它将不会触发。这个状态在 isMouseDown 中被跟踪。

完整的源代码作为参考:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <style type="text/css" media="screen">
    table td {
      width:100px;
      height:100px;
      text-align:center;
      vertical-align:middle;
      background-color:#ccc;
    }

    table td.highlighted {
      background-color:#999;
    }
  </style>
</head>
<body>
  <table cellpadding="0" cellspacing="1" id="our_table">
    <tr>
      <td>a</td>
      <td>b</td>
      <td>c</td>
    </tr>
    <tr>
      <td>d</td>
      <td>e</td>
      <td>f</td>
    </tr>
    <tr>
      <td>g</td>
      <td>h</td>
      <td>i</td>
    </tr>
  </table>

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
  <script type="text/javascript" charset="utf-8">
    $(function () {
      var isMouseDown = false;
      $("#our_table td")
        .mousedown(function () {
          isMouseDown = true;
          $(this).toggleClass("highlighted");
          return false; // prevent text selection
        })
        .mouseover(function () {
          if (isMouseDown) {
            $(this).toggleClass("highlighted");
          }
        })
        .bind("selectstart", function () {
          return false; // prevent text selection in IE
        });

      $(document)
        .mouseup(function () {
          isMouseDown = false;
        });
    });
  </script>
</body>
</html>

2
有趣的是你使用了toggleClass...在这种情况下,当你悬停回到一个已经被选中的单元格时,它会取消选择。根据应用程序逻辑,这可能是正确的,也可能不正确。直觉上(就像我在我的解决方案中所做的那样),我会一直保持所有选定状态,直到鼠标抬起。 - Jaanus
1
请查看备用链接 :) 我刚刚添加了它。 - August Lilleaas
1
使用toggleClass只是一种“hack”,可以这么说。在一个适当的可单元测试的实现中,您将使用一个带有布尔值的实例,或类似的东西。 - August Lilleaas
1
另外,更改状态逻辑以便在鼠标抬起时取消选择所有内容(这就是您所描述的,对吧?)非常简单。在此情况下,在mouseup事件上执行$("#our_table td").removeClass("highlighted")将是适当的hack。 - August Lilleaas
2
对于那些希望在通过ajax新创建的表上运行此代码的人,请参见此Fiddle:http://jsfiddle.net/Brv6J/803/ - MackieeE
显示剩余7条评论

18

如果你想要类似电子表格的单元格选择(按列/行区块),你需要在鼠标悬停事件中突出显示每一行中介于起始索引和结束索引之间的每个单元格:

for (var i = rowStart; i <= rowEnd; i++) {
    var rowCells = table.find("tr").eq(i).find("td");
    for (var j = cellStart; j <= cellEnd; j++) {
        rowCells.eq(j).addClass("selected");
    }        
}

由于用户可能从各个方向(自上而下、自下而上、自右向左、自左向右)开始选择单元格,你需要为起始和结束分配正确的索引。

这里是一个jsFiddle


最好使用Dojo或jQuery(或者更高级的东西)。 - paulsm4
mouseover 函数中添加 table.find(".selected").removeClass("selected"); 以使其更像电子表格,即在移动到选定区域时取消选择单元格。更新的 fiddle - Slartibartfast
这很棒,可以与 shift 选择一起使用。如果它也支持 ctrl 选择,那就太棒了。 - Gigi

14

你能否轻松地重构一下,以支持触摸事件? - hlyates
@hlyates,您有关于如何重构类似这样的代码以支持触摸事件的建议吗? - maco1717

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接