将jquery事件应用于表中的特定区域或行

Apply a jquery event to a specific range or rows in a table

本文关键字:区域 jquery 事件 应用于      更新时间:2023-09-26

我在中继器中有一个表。数据被输入到表中,并根据加载的数据类型为每一行分配一个类。例如:

 <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行。我有一个事件处理程序,可以在单击时执行此操作。

我需要对具有特定值的项目应用完整的细节展开(类型a到类型C)。当typeA中单元格的值等于从查询字符串接收到的值时,我需要在父级和该父级的所有子级上触发展开事件。我已经有一些代码可以做到这一点了。然而,我觉得这有点像黑客。我想知道有没有人有什么建议?这是我迄今为止所拥有的。

 $(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增加一以指向下一行。while循环检查每一行的类。在每行上触发展开事件,直到命中下一个typeA行。这样可以正确地展开每一行。但是,我还是jquery的新手,我觉得可能有一些方法可以更好地实现这一点。有什么想法吗?

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

//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

以下是您的一些文档:

  • .slice():http://api.jquery.com/slice
  • .eq():http://api.jquery.com/eq
  • .text():http://api.jquery.com/text

此外,您可以将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增加一,因为如果通过for循环的第一次迭代触发了expandRows()函数,那么它将传递一个零索引,该索引将针对最上面的行(你在开始时从选择器中排除了它)。

$(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');
     }
  }
});