我正在寻找一种使用jQuery扩展/折叠分层表行的有效方法。问题是,扩展和折叠功能不同。
level_0
的行,所有其他行都被隐藏。id=10
应该只显示id=11
和id=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代码。
感谢任何提示。
答案 0 :(得分:2)
你帖子中的表格html无效(由td包围)。在结构合理的表上,此代码可以正常工作。
$("tr.level_0").live("click", function () {
$(this).nextUntil(".level_0").toggle();
});
答案 1 :(得分:0)
我认为您需要更多一些代码,以便您可以处理关闭和打开中所有行的点击次数状态。
我添加了一个类开关来指示行何时打开,并根据其状态以不同方式处理点击。 collapse
和expand
都有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);