jQuery UI手风琴如何保持多个部分展开?

100

我可能很蠢,但你怎样才能让jQuery UI的手风琴控件中保持多个部分打开?所有演示都只有一个打开...我正在寻找一种可折叠的菜单类型系统。


18
请看这个链接:http://jsfiddle.net/DkHyd/ - supersuphot
你的插件真是太完美了!非常感谢,伙计! - SexyBeast
14个回答

125

非常简单:

<script type="text/javascript">
    (function($) {
        $(function() {
            $("#accordion > div").accordion({ header: "h3", collapsible: true });
        })
    })(jQuery);
</script>

<div id="accordion">
    <div>
        <h3><a href="#">First</a></h3>
        <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
    </div>
    <div>
        <h3><a href="#">Second</a></h3>
        <div>Phasellus mattis tincidunt nibh.</div>
    </div>
    <div>
        <h3><a href="#">Third</a></h3>
        <div>Nam dui erat, auctor a, dignissim quis.</div>
    </div>
</div>

1
很好用。我添加了以下代码以开始折叠: $(event.target).accordion( "activate", false ); }``` - forresto
2
太棒了。很高兴它对你起作用了。 :) 我喜欢尽可能保持简单。 - 2upmedia
7
在jQuery-UI 1.10中,如果想要初始折叠,而不是使用以下代码: create: function(event) { $(event.target).accordion( "activate", false ); } 你可以设置选项: {active: false} - damko
18
为每个模块单独配备手风琴。 - Paul Annekov
3
这是我用来测试的jsFiddle链接:http://jsfiddle.net/txo8rx3q/1/。我还添加了一些CSS,以防止展开的手风琴部分看起来像是被选中。 - Matthew Lock
显示剩余5条评论

96

这个最初讨论jQuery UI手风琴文档中:

NOTE: If you want multiple sections open at once, don't use an accordion

An accordion doesn't allow more than one content panel to be open at the same time, and it takes a lot of effort to do that. If you are looking for a widget that allows more than one content panel to be open, don't use this. Usually it can be written with a few lines of jQuery instead, something like this:

jQuery(document).ready(function(){
  $('.accordion .head').click(function() {
      $(this).next().toggle();
      return false;
  }).next().hide();
});

Or animated:

jQuery(document).ready(function(){
  $('.accordion .head').click(function() {
      $(this).next().toggle('slow');
      return false;
  }).next().hide();
});

"我可能是个白痴" - 如果你不阅读文档,你并不是一个白痴,但如果你遇到问题,通常阅读文档会加速找到解决方案。


9
这个解决方案没有进行手风琴样式的任何处理。 - forresto
15
此外,这根本不是问题的解决方案。手风琴文档和选项、事件列表等都很差劲。而且他们不应该告诉用户“如果我们没有你需要的选项-就不要使用它!”,而应该说“很抱歉目前还没有此选项,但欢迎任何为我们的插件增加功能的贡献者”。 - artgrohe
我引用的文本已从文档中删除。我添加了一个指向存档版本的链接。 - MvanGeest
1
请记住,jQuery UI手风琴不仅可以创建实际的手风琴效果,还为屏幕阅读器添加了大量的可访问性标记。 - Brian
5
这没有任何意义。如果音乐家的手臂很开,手风琴可以打开所有褶皱;如果仪器的两半紧挨在一起,手风琴可以关闭所有褶皱;或者介于两者之间。如果词有任何意义,那么手风琴软件UI控件应该允许任意组合的打开和关闭面板。 - birdus
显示剩余2条评论

85

我在一个类似的帖子中发布了这个帖子,但认为它在这里也可能相关。

使用单个jQuery-UI手风琴实现此目标

正如其他人指出的那样,Accordion插件没有直接实现此功能的API选项。然而,如果由于某种原因你必须使用该插件(例如,你要维护一个现有系统),你可以使用beforeActivate事件处理程序选项来颠覆并模拟插件的默认行为来实现这个目标。

例如:

$('#accordion').accordion({
    collapsible:true,

    beforeActivate: function(event, ui) {
         // The accordion believes a panel is being opened
        if (ui.newHeader[0]) {
            var currHeader  = ui.newHeader;
            var currContent = currHeader.next('.ui-accordion-content');
         // The accordion believes a panel is being closed
        } else {
            var currHeader  = ui.oldHeader;
            var currContent = currHeader.next('.ui-accordion-content');
        }
         // Since we've changed the default behavior, this detects the actual status
        var isPanelSelected = currHeader.attr('aria-selected') == 'true';

         // Toggle the panel's header
        currHeader.toggleClass('ui-corner-all',isPanelSelected).toggleClass('accordion-header-active ui-state-active ui-corner-top',!isPanelSelected).attr('aria-selected',((!isPanelSelected).toString()));

        // Toggle the panel's icon
        currHeader.children('.ui-icon').toggleClass('ui-icon-triangle-1-e',isPanelSelected).toggleClass('ui-icon-triangle-1-s',!isPanelSelected);

         // Toggle the panel's content
        currContent.toggleClass('accordion-content-active',!isPanelSelected)    
        if (isPanelSelected) { currContent.slideUp(); }  else { currContent.slideDown(); }

        return false; // Cancels the default action
    }
});

查看jsFiddle演示


6
谢谢!这是最好的解决方案,因为它不需要更改您现有的任何环境。 - artgrohe
它需要jQuery UI 1.9.0+(Drupal 7仅支持1.8.7)。 - Capi Etheriel
1
我相信活动类已经改变为 ui-accordion-header-active - Tim Vermaelen
不错的解决方案。我添加了animate选项的检测:var animate = $(this).accordion("option", "animate"); if(selected) animate === false ? currContent.hide() : toString.call(animate) === '[object String]' ? currContent.slideUp({ easing: animate }) : currContent.slideUp(animate); else animate === false ? currContent.show() : toString.call(animate) === '[object String]' ? currContent.slideDown({ easing: animate }) : currContent.slideDown(animate); - swornabsent
1
如果我们有多个手风琴,该如何处理呢?因为当我们只想在一个手风琴上实现它时,它会打开所有其他手风琴。谢谢。 - Gian Almada
显示剩余6条评论

22

甚至更简单?

<div class="accordion">
    <h3><a href="#">First</a></h3>
    <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
</div>    
<div class="accordion">
    <h3><a href="#">Second</a></h3>
    <div>Phasellus mattis tincidunt nibh.</div>
</div>         
<div class="accordion">
    <h3><a href="#">Third</a></h3>
    <div>Nam dui erat, auctor a, dignissim quis.</div>
</div>
<script type="text/javascript">
    $(".accordion").accordion({ collapsible: true, active: false });
</script>

这个我觉得很不错。简单的解决方案解决了我在处理大量手风琴项目时遇到的性能问题。令人惊讶的是,初始化一组大型手风琴表现良好。谢谢! - Pure Function

14

我做了一个 jQuery 插件,它具有与 jQuery UI 手风琴相同的外观,并且可以保持所有选项卡\部分打开。

你可以在这里找到它

http://anasnakawa.wordpress.com/2011/01/25/jquery-ui-multi-open-accordion/

能够使用相同的标记

<div id="multiOpenAccordion">
        <h3><a href="#">tab 1</a></h3>
        <div>Lorem ipsum dolor sit amet</div>
        <h3><a href="#">tab 2</a></h3>
        <div>Lorem ipsum dolor sit amet</div>
</div>

Javascript代码

$(function(){
        $('#multiOpenAccordion').multiAccordion();
       // you can use a number or an array with active option to specify which tabs to be opened by default:
       $('#multiOpenAccordion').multiAccordion({ active: 1 });
       // OR
       $('#multiOpenAccordion').multiAccordion({ active: [1, 2, 3] });

       $('#multiOpenAccordion').multiAccordion({ active: false }); // no opened tabs
});

更新: 该插件已更新,支持默认活动选项卡选项。

更新: 该插件现已不再使用。


伟大的解决方案。 - Trimantra Software Solution

7

简单来说:激活手风琴效果的类,然后使用它创建div,就像手风琴的多个实例一样。

示例如下:

JS

$(function() {
    $( ".accordion" ).accordion({
        collapsible: true,
        clearStyle: true,
        active: false,
    })
});

HTML

<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>
<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>
<div class="accordion">
    <h3>Title</h3>
    <p>lorem</p>
</div>

https://jsfiddle.net/sparhawk_odin/pm91whz3/


1
我尝试了帖子中的所有答案,这个是最好的。使用最新的jquery和jqueryUI,其他解决方案现在存在许多样式问题。这是2017年的更新:https://jsfiddle.net/rambutan2000/eqbbgb7g/ - Geordie
@Geordie 我很高兴能帮到你。 - Giovan Cruz

6
实际上我在网上寻找解决方法已经有一段时间了。接受的答案给出了好的“按照书本来做”的答案。但我不想接受那个答案,所以我继续搜索并找到了这个:http://jsbin.com/eqape/1601/edit - 实时示例。该示例同时引入了适当的样式并添加了所请求的功能,完全可以在每次标题单击时添加自己的功能。还允许多个div位于“h3”之间。
 $("#notaccordion").addClass("ui-accordion ui-accordion-icons ui-widget ui-helper-reset")
  .find("h3")
    .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
    .hover(function() { $(this).toggleClass("ui-state-hover"); })
    .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
    .click(function() {
      $(this).find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()


        .next().toggleClass("ui-accordion-content-active").slideToggle();
        return false;
    })
    .next()
      .addClass("ui-accordion-content  ui-helper-reset ui-widget-content ui-corner-bottom")
      .hide();

HTML 代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Toggle Panels (not accordion) using ui-accordion  styles</title>

<!-- jQuery UI  |  http://jquery.com/  http://jqueryui.com/  http://jqueryui.com/docs/Theming  -->
<style type="text/css">body{font:62.5% Verdana,Arial,sans-serif}</style>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>


</head>
<body>

<h1>Toggle Panels</h1>
<div id="notaccordion">
  <h3><a href="#">Section 1</a></h3>
  <div class="content">
    Mauris mauris  ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus  nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a  nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur  malesuada. Vestibulum a velit eu ante scelerisque vulputate.
  </div>
  <h3><a href="#">Section 2</a></h3>
  <div>
    Sed non urna. Donec et ante. Phasellus eu ligula.  Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet,  mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo.  Vivamus non quam. In
    suscipit faucibus urna.
  </div>
  <h3><a href="#">Section 3</a></h3>
  <div class="top">
  Top top top top
  </div>
  <div class="content">
    Nam enim risus, molestie et, porta ac, aliquam ac,  risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede.  Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed  commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo  purus venenatis dui.
    <ul>
      <li>List item one</li>
      <li>List item two</li>
      <li>List item  three</li>
    </ul>
  </div>
  <div class="bottom">
  Bottom bottom bottom bottom
  </div>
  <h3><a href="#">Section 4</a></h3>
  <div>
    Cras dictum. Pellentesque habitant morbi tristique  senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante  ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae;  Aenean lacinia
    mauris vel est.
    Suspendisse eu nisl. Nullam ut libero. Integer  dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per  conubia nostra, per
    inceptos himenaeos.
  </div>
</div>

</body>
</html>`

5
我找到了一个巧妙的解决方案。我们可以调用同一个函数两次,但使用不同的ID。
$(function() {
    $( "#accordion1" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
    $( "#accordion2" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
});

HTML代码

<div id="accordion1">
    <h3>Section 1</h3>
    <div>Section one Text</div>
</div>
<div id="accordion2">   
    <h3>Section 2</h3>
    <div>Section two Text</div>
</div>

3
建议您采用其他人建议的基于“class”的单一选择器,这样可以避免重复代码(DRY)。 - Scotty.NET

4

简单来说,创建多个手风琴式的div,每个div代表一个锚点标签,例如:

<div>
<div class="accordion">
<a href = "#">First heading</a>
</div>
<div class="accordion">
<a href = "#">First heading</a>
</div>
</div>

它添加了一些标记。但像专业人士一样工作...


2
更简单的做法是,在每个li标签的class属性中加上标签名称,然后使用jquery遍历每个li标签来初始化手风琴效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接