jQuery展开/折叠分层表行

时间:2010-08-24 08:02:23

标签: javascript jquery expand

我正在寻找一种使用jQuery扩展/折叠分层表行的有效方法。问题是,扩展和折叠功能不同。

  • 最初,只显示类level_0的行,所有其他行都被隐藏。
  • 展开应该只显示下一个级别,因此点击行id=10应该只显示id=11id=14的行。
  • 另一方面,
  • 崩溃,应该折叠所有连续行,其行的级别比当前行更深。例如,单击行id=10上的折叠应隐藏具有ID 11, 12, 13, 14的行(如果它们可见)。

表格数据如下:

<table id="mytable">
    <tr class="level_0" id="10">...</td>
    <tr class="level_1 parent_10" id="11">...</td>
    <tr class="level_2 parent_11" id="12">...</td>
    <tr class="level_2 parent_11" id="13">...</td>
    <tr class="level_1 parent_10" id="14">...</td>
    <tr class="level_0" id="15">...</td>
</table>

我的非工作解决方案:

$('#mytable tr').live('click', function() {
  var toggleClass = 'parent_' + $(this).attr('id');
  $(this).nextAll('tr').each(function() {
    if ($(this).is('.'+toggleClass)) {
      $(this).toggleClass("showme");
    }
  });
});

问题是,它只会折叠下一级行。仍会显示点击行下方的可见和更深级别的行。


任何人都可以给我一些关于如何以有效的方式做到这一点的提示吗?如果需要,可以调整HTML代码。

感谢任何提示。

3 个答案:

答案 0 :(得分:2)

你帖子中的表格html无效(由td包围)。在结构合理的表上,此代码可以正常工作。

$("tr.level_0").live("click", function () {
  $(this).nextUntil(".level_0").toggle();
});

答案 1 :(得分:0)

我认为您需要更多一些代码,以便您可以处理关闭打开所有行的点击次数状态。

我添加了一个类开关来指示行何时打开,并根据其状态以不同方式处理点击。 collapseexpand都有while循环遍历行,从紧跟在单击行之后的循环开始,并且当它们到达相同级别的行时它们停止。这个逻辑应该适用于任何级别,而不仅仅是0.此外,while循环可能更清晰,使用nextUntil逻辑与花式选择器 - 我不熟悉jQuery方法,直到看到Jules的答案 - 非常光滑!

另外,为了使这个示例代码更简单,我将您的级别类命名系统视为HTML数据属性,因此给定的行如下所示:<tr data-level="0" id="10">。您可以使用代码替换对.data的调用来解析您的类名。

var $rows = $('#mytable tr');

$rows.live('click', function() {
$(this).toggleClass('open');

if ($this.hasClass('open')){
    collapse($(this));
} else {
    expand($this);
}
}

function collapse ($row) {
    $row.removeClass('open');
var rowIndex = $rows.index($row);
var siblingOrAncestorRowFound = false;

while (!siblingOrAncestorRowFound){
    var $nextRow = $rows.eq(rowIndex + 1);
    if ($nextRow.level  > $row.level){
        $nextRow.hide().removeClass('open');
        rowIndex++;
    } else {
        siblingOrAncestorRowFound = true;
    }
}
}

function expand ($row) {
    $row.addClass('open')
var rowIndex = $rows.index($row);
var siblingOrAncestorRowFound = false;

while (!siblingOrAncestorRowFound){
    var $nextRow = $rows.eq(rowIndex + 1);
    if ($nextRow.level  > $row.level){

        // only show rows exactly one level below
        if ($nextRow.level == $row.level + 1){
            $nextRow.show();
        }

        rowIndex++;
    } else {
        siblingOrAncestorRowFound = true;
    }
}
}

(这没有经过测试 - 抱歉打算解雇!)

答案 2 :(得分:0)

我为multiple levels of hierarchy as an answer to another question创建了一个版本。

您桌子的jQuery将是:

var treeTable = {
    parentClassPrefix : '',
    collapsedClass : 'collapsed',
    init : function(parentClassPrefix) {
        this.parentClassPrefix = parentClassPrefix;
        $('table').on('click', 'tr', function () { 
            treeTable.toggleRowChildren($(this));
        });
    },
    toggleRowChildren : function(parentRow) {
        var childClass = this.parentClassPrefix+parentRow.attr('id');
        var childrenRows = $('tr', parentRow.parent()).filter('.'+childClass);
        childrenRows.toggle();
        childrenRows.each(function(){
            if (!$(this).hasClass(treeTable.collapsedClass)) {
                treeTable.toggleRowChildren($(this));
            }
        });
        parentRow.toggleClass(this.collapsedClass);
    }
};

treeTable.init('parent_');

请参阅此JSFiddle了解它的工作原理。

的优化

我有一个稍微不同的表结构,它涉及指定父项和子项,以便搜索更有效。

然后我也从它做了jQuery hierarchical table row toggling Gist并将其转换为带优化的客观化javascript。优化来自http://24ways.org/2011/your-jquery-now-with-less-suck/

具体做法是:

桌面上的事件委派而不是行。

$('table').on('click', 'tr.'+treeTable.parentClass, function () {
    treeTable.toggleRowChildren($(this));
});

缓存子项选择。

使用更快的元素选择器,然后使用.childClass上的慢速过滤器

var childrenRows = $('tr', parentRow.parent()).filter('.'+childClass);
相关问题