使用JQuery展开/折叠表格行

我想在单击标题列时展开和折叠表格行。 我只想展开/折叠在特定标题(点击)下的行。

这是我的表结构:

<table border="0"> <tr> <td colspan="2">Header</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td colspan="2">Header</td> </tr> <tr> <td>date</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> </table> 

关于如何完成这个任务的任何想法。 使用div这个任务似乎很简单,但我有表格数据,我想操纵。

我可以想到的一个想法是在每一行中使用css类,每行都在每个标题下,并使用JQuery来扩展/折叠这些行,只有单击标题时。 但是,如果我的表有10-15头,那么跟踪css类似乎很难。

请build议一个合适的方法来实现这一点。

你可以试试这个方法:

给标题行指定一个类header ,使用nextUntil获取点击标题下的所有行,直到下一个标题。

JS

 $('.header').click(function(){ $(this).nextUntil('tr.header').slideToggle(1000); }); 

HTML

 <table border="0"> <tr class="header"> <td colspan="2">Header</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> 

演示

另一个例子:

 $('.header').click(function(){ $(this).find('span').text(function(_, value){return value=='-'?'+':'-'}); $(this).nextUntil('tr.header').slideToggle(100); // or just use "toggle()" }); 

演示

在animation切换的情况下,您也可以使用承诺在完成切换后切换跨度图标/文本。

 $('.header').click(function () { var $this = $(this); $(this).nextUntil('tr.header').slideToggle(100).promise().done(function () { $this.find('span').text(function (_, value) { return value == '-' ? '+' : '-' }); }); }); 

。诺言()

.slideToggle()

或者只是用一个CSS伪元素来表示扩展/折叠的符号,只需在头上切换一个类即可。

CSS: –

 .header .sign:after{ content:"+"; display:inline-block; } .header.expand .sign:after{ content:"-"; } 

JS: –

 $(this).toggleClass('expand').nextUntil('tr.header').slideToggle(100); 

演示

在不改变基于HTML table的结构的情况下,最简单的方法是在包含头文件的tr元素(例如.header上使用一个类名,以便:

 <table border="0"> <tr class="header"> <td colspan="2">Header</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr class="header"> <td colspan="2">Header</td> </tr> <tr> <td>date</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> <tr> <td>data</td> <td>data</td> </tr> </table> 

和jQuery:

 // bind a click-handler to the 'tr' elements with the 'header' class-name: $('tr.header').click(function(){ /* get all the subsequent 'tr' elements until the next 'tr.header', set the 'display' property to 'none' (if they're visible), to 'table-row' if they're not: */ $(this).nextUntil('tr.header').css('display', function(i,v){ return this.style.display === 'table-row' ? 'none' : 'table-row'; }); }); 

JS小提琴演示 。

在链接的演示中,我使用CSS来隐藏没有 header类名的tr元素; 但在实践中(尽pipeJavaScript禁用的用户相对稀less),我build议使用JavaScript来添加相关的类名称,隐藏和显示适当的:

 // hide all 'tr' elements, then filter them to find... $('tr').hide().filter(function () { // only those 'tr' elements that have 'td' elements with a 'colspan' attribute: return $(this).find('td[colspan]').length; // add the 'header' class to those found 'tr' elements }).addClass('header') // set the display of those elements to 'table-row': .css('display', 'table-row') // bind the click-handler (as above) .click(function () { $(this).nextUntil('tr.header').css('display', function (i, v) { return this.style.display === 'table-row' ? 'none' : 'table-row'; }); }); 

JS小提琴演示 。

参考文献:

  • addClass()
  • click()
  • css()
  • filter()
  • find()
  • hide()
  • nextUntil()

我会说使用data-属性来匹配头里面的元素。 小提琴: http : //jsfiddle.net/GbRAZ/1/

HTML更改的预览:

  <tr class="header" id="header1"> <td colspan="2">Header</td> </tr> <tr data-for="header1" style="display:none"> <td>data</td> <td>data</td> </tr> <tr data-for="header1" style="display:none"> <td>data</td> <td>data</td> </tr> 

JS代码:

 $(".header").click(function () { $("[data-for="+this.id+"]").slideToggle("slow"); }); 

编辑 :但是,它涉及到一些HTML更改。 所以我不知道,如果那就是你想要的。 更好的方法来构build这将是使用<th>或通过更改整个HTML使用ul, ol, etc ,甚至是一个div > span设置。

我喜欢最简单的答案。 不过,我不喜欢倒塌的倒挂。 所以我结合了这个问题的一个解决scheme: 如何在表行上使用slideDown(或show)函数? 当行向上或向下滑动时使其更平滑。 它涉及不得不将每个td的内容包装在一个div中。 这使得它能够平滑地animation崩溃。 当行被展开时,它将replacediv,只是内容。

所以这里是html:

 <table> <tr class="header"> <td>CARS</td> </tr> <tr class="thing"> <td>car</td> </tr> <tr class="thing"> <td>truck</td> </tr> <tr class="header"> <td>HOUSES</td> </tr> <tr class="thing"> <td>split level</td> </tr> <tr class="thing"> <td>trailer</td> </tr> 

这里是js

 $('.header').click(function(){ if($(this).hasClass("collapsed")){ $(this).nextUntil('tr.header') .find('td') .parent() .find('td > div') .slideDown("fast", function(){ var $set = $(this); $set.replaceWith($set.contents()); }); $(this).removeClass("collapsed"); } else { $(this).nextUntil('tr.header') .find('td') .wrapInner('<div style="display: block;" />') .parent() .find('td > div') .slideUp("fast"); $(this).addClass("collapsed"); } }); 

结帐这个小提琴的例子https://jsfiddle.net/p9mtqhm7/52/

我扩大了其中一个答案,但是我的function有点不同。 在我的版本中,不同的行形成不同的组。 并且“标题”行触发了该特定组的合拢/扩展。 另外,每个小组都记住它的状态。听起来有点混乱,你可以使用jsfiddle来testing我的版本。 希望这个代码片段将有助于有人在那里!

HTML

 <table border="0"> <tr> <th>Header 1</th> <th>Header 2</th> </tr> <tr> <td class='group1'>Group 1</td> <td>data 2</td> </tr> <tr class='group1'> <td>data 3</td> <td>data 4</td> </tr> <tr> <td class='group2'>Group 2</td> <td>data 2</td> </tr> <tr class='group2'> <td>data 3</td> <td>data 4</td> </tr> <tr class='group2'> <td class='sub_group1'>Sub Group 1</td> <td>data 6</td> </tr> <tr class='group2 sub_group1'> <td>data 7</td> <td>data 8</td> </tr> <tr class='group2 sub_group1'> <td>data 9</td> <td>data 10</td> </tr> <tr class='group2 sub_group1'> <td class='sub_sub_group1'>Sub Sub Group 1</td> <td>data 11</td> </tr> <tr class='group2 sub_group1 sub_sub_group1'> <td>data 12</td> <td>data 13</td> </tr> <tr class='group2 sub_group1 sub_sub_group1'> <td>data 14</td> <td>data 15</td> </tr> <tr class='group2'> <td class='sub_group2'>Sub Group 2</td> <td>data 11</td> </tr> <tr class='group2 sub_group2'> <td>data 12</td> <td>data 13</td> </tr> <tr class='group2 sub_group2'> <td>data 14</td> <td>data 15</td> </tr> </table> 

CSS

 table, tr, td, th { border: 1px solid black; border-collapse:collapse; } img.button_open{ content:url('http://code.stephenmorley.org/javascript/collapsible-lists/button-open.png'); cursor:pointer; } img.button_closed{ content: url('http://code.stephenmorley.org/javascript/collapsible-lists/button-closed.png'); cursor:pointer; } 

JS

 function CreateGroup(group_name) { // Create Button(Image) $('td.' + group_name).prepend("<img class='" + group_name + " button_closed'> "); // Add Padding to Data $('tr.' + group_name).each(function () { var first_td = $(this).children('td').first(); var padding_left = parseInt($(first_td).css('padding-left')); $(first_td).css('padding-left', String(padding_left + 25) + 'px'); }); RestoreGroup(group_name); // Tie toggle function to the button $('img.' + group_name).click(function(){ ToggleGroup(group_name); }); } function ToggleGroup(group_name) { ToggleButton($('img.' + group_name)); RestoreGroup(group_name); } function RestoreGroup(group_name) { if ($('img.' + group_name).hasClass('button_open')) { // Open everything $('tr.' + group_name).show(); // Close subgroups that been closed $('tr.' + group_name).find('img.button_closed').each(function () { sub_group_name = $(this).attr('class').split(/\s+/)[0]; //console.log(sub_group_name); RestoreGroup(sub_group_name); }); } if ($('img.' + group_name).hasClass('button_closed')) { // Close everything $('tr.' + group_name).hide(); } } function ToggleButton(button) { $(button).toggleClass('button_open'); $(button).toggleClass('button_closed'); } CreateGroup('group1'); CreateGroup('group2'); CreateGroup('sub_group1'); CreateGroup('sub_group2'); CreateGroup('sub_sub_group1'); 

DEMO

使用jQuery这很容易…

  $('YOUR CLASS SELECTOR').click(function(){ $(this).toggle(); }); 

一个JavaScript手风琴可以做到这一点。

W3Schools这个小提琴使得一个简单的任务,甚至更简单的使用什么,除了JavaScript,我下面部分重现。

 <head> <style> button.accordion { background-color: #eee; color: #444; font-size: 15px; cursor: pointer; } button.accordion.active, button.accordion:hover { background-color: #ddd; } div.panel { padding: 0 18px; display: none; background-color: white; } div.panel.show { display: block; } </style> </head><body> <script> var acc = document.getElementsByClassName("accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].onclick = function(){ this.classList.toggle("active"); this.nextElementSibling.classList.toggle("show"); } } </script> ... <button class="accordion">Section 1</button> <div class="panel"> <p>Lorem ipsum dolor sit amet</p> </div> ... <button class="accordion">Table</button> <div class="panel"> <p><table name="detail_table">...</table></p> </div> ... <button class="accordion"><table name="button_table">...</table></button> <div class="panel"> <p>Lorem ipsum dolor sit amet</p> <table name="detail_table">...</table> <img src=...></img> </div> ... </body></html> 

如果使用php,不要忘记将其转换为" to '也可以使用button内的数据表,它仍然可以工作。