将jquery事件应用于表中的特定范围或行

时间:2012-02-06 17:18:02

标签: javascript jquery jquery-selectors

我在转发器中有一张桌子。数据将输入到表中,并根据所加载的数据类型为每一行分配一个类。例如:

 <table id="detail-table">
      <tr class="typeA">
           <td>Value</td>
      </tr>
      <tr class="typeB">
           <td>Value</td>
      </tr>
      <tr class="typeC">
           <td>Value</td>
      </tr>
      <tr class="typeB">
           <td>Value</td>
      </tr>
      <tr class="typeA">
           <td>Value</td>
      </tr>
 </table>

该表是折叠表。 typeA是标题,typeB是typeA的子类,typeC是typeB的子类。在表格示例中,typeA有两个直接子节点,第一个子节点也有一个子节点。

当用户单击typeA时,会出现两个typeB行,当typeB有子项时,它也会展开以显示typeC行。我有一个事件处理程序,可以在点击时执行此操作

我需要为具有特定值的项目应用完整的详细信息扩展(typeA到typeC)。当typeA中的单元格的值等于从查询字符串接收的值时,我需要在父级和父级的所有子级上触发expand事件。我有一些代码可以做到这一点。但是,我觉得这有点像黑客。我想知道是否有人有一些建议?这是我到目前为止所拥有的。

 $(function() {
      var tableRows = $('#detail-table').find("tr:gt(0)");
      $(tableRows).each(function(i, val) {
           //ExpandValue is a value in my C# page.
           if ($.trim(val.cells[0].innerText) == '<%= ExpandValue %>'){
                expandRows(i);
           }
      }

      function expandRows(startIndex) {
           // Expand the first row, the typeA class
           // row that matches the value
           $(tableRows[startIndex]).trigger('expand');
           startIndex += 1;
           while($(tableRows[startIndex]).attr("class") != "typeA"){
                $(tableRows[startIndex]).trigger('expand');
                startIndex++;
           }
      }
 });

这会查找表的所有行。然后循环遍历表行数组。条件检查每行中第一个单元格的innerText。如果单元格的innerText与ExpandValue匹配,则找到目标行。将此行的索引发送到expandRows函数。在expandRows函数中,展开startIndex处的行,这是与ExpandValue匹配的typeA类行。然后将startIndex增加1以指向下一行。 while循环检查每一行的类。在每一行上触发expand事件,直到命中下一个typeA行。这可以正常工作和扩展每一行。但同样,我是jquery的新手,我觉得可能有一些方法可以更好地完成这个任务。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以加速选择器并在代码顶部循环:

//instead of using a pseudo-selector, we can use the `slice()` function to get all but the first element returned
var $tableRows = $('#detail-table').find("tr").slice(1);

//this `for` loop will perform a lot faster than the `.each()` loop
for (var i = 0, len = $tableRows.length; i < len; i++) {
    if ($.trim($tableRows.eq(i).find('td').eq(0).text()) == '<%= ExpandValue %>') {
        expandRows(i);
    }
}

以下演示了正确格式化的for循环比使用jQuery的.each() http://jsperf.com/jquery-each-vs-for-loops/2

更快的速度

以下是ya的一些文档:

另外,你继续将你的tableRows变量包装在jQuery中,这不是必需的,因为它从一开始就已经是一个jQuery对象了。

 $(function() {
      var $tableRows = $('#detail-table').find("tr").slice(1);
      for (var i = 0, len = $tableRows.length; i < len; i++) {
          if ($.trim($tableRows.eq(i).find('td').eq(0).text()) == '<%= ExpandValue %>') {
              expandRows(i);
          }
      }

      function expandRows(startIndex) {
           // Expand the first row, the typeA class
           // row that matches the value
           $tableRows.eq(startIndex).trigger('expand');
           startIndex++;
           while($tableRows.eq(startIndex).attr("class") != "typeA"){
                $tableRows.eq(startIndex).trigger('expand');
                startIndex++;
           }
      }
 });

我不确定这是否已经做了你想做的事情但是在你的expandRows函数上你应该在做任何事情之前将startIndex增加一,因为如果第一次迭代通过{{1}循环触发for函数,然后它将传递一个零索引,该索引将定位到顶行(在开始时从选择器中排除)。

答案 1 :(得分:1)

$(function(){
  var $list = $('#detail-table tr.typeA:gt(0) > td:eq(0):contains("<%= ExpandValue %>")');
  for (var i = 0, len = $list.length; i < len; i++)
  {
     var $nextrows = $list[i].nextAll("tr");
     for (var x = 0, ilen = $nextrows.length; x < ilen; x++)
     {
        if ($nextrows[x].hasClass("typeA")) break;
        $nextrows[x].trigger('expand');
     }
  }
});