36

我在一个项目中使用jQuery UI Accordion(它一次不允许打开多个项目)。使用手风琴是合适的,因为我通常希望一次打开一个面板。

但是,我需要提供一个“全部展开”链接,单击该链接会切换到“全部折叠”。我不想围绕这一要求自定义编写几乎相同的手风琴功能,所以我想要一些 JS 来实现这一点,同时保持手风琴组件的使用。

问题:在仍然使用 jQuery UI“Accordion”组件来支持标准功能的同时,需要什么 JavaScript/jQuery 来实现这一点?

这是一个小提琴:http: //jsfiddle.net/alecrust/a6Cu7/

4

14 回答 14

53

正如jQuery UI 论坛中所讨论的,您不应该为此使用手风琴。

如果你想要一些看起来和行为都像手风琴的东西,那很好。使用他们的类来设置样式,并实现您需要的任何功能。然后添加一个按钮来打开或关闭它们非常简单。例子

HTML

通过使用 jquery-ui 类,我们让我们的手风琴看起来就像“真正的”手风琴一样。

<div id="accordion" class="ui-accordion ui-widget ui-helper-reset">
    <h3 class="accordion-header ui-accordion-header ui-helper-reset ui-state-default ui-accordion-icons ui-corner-all">
        <span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-e"></span>
        Section 1
    </h3>
    <div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom">
        Content 1
    </div>
</div>​

滚动你自己的手风琴

大多数情况下,我们只希望手风琴标题切换以下兄弟的状态,这是它的内容区域。我们还添加了两个自定义事件“show”和“hide”,稍后我们将加入它们。

var headers = $('#accordion .accordion-header');
var contentAreas = $('#accordion .ui-accordion-content ').hide();
var expandLink = $('.accordion-expand-all');

headers.click(function() {
    var panel = $(this).next();
    var isOpen = panel.is(':visible');

    // open or close as necessary
    panel[isOpen? 'slideUp': 'slideDown']()
        // trigger the correct custom event
        .trigger(isOpen? 'hide': 'show');

    // stop the link from causing a pagescroll
    return false;
});

展开/折叠全部

我们使用布尔isAllOpen标志来标记按钮何时被更改,这可以很容易地成为一个类,或者一个更大的插件框架上的状态变量。

expandLink.click(function(){
    var isAllOpen = $(this).data('isAllOpen');

    contentAreas[isAllOpen? 'hide': 'show']()
        .trigger(isAllOpen? 'hide': 'show');
});

“全开”时交换按钮

多亏了我们自定义的“显示”和“隐藏”事件,我们可以在面板发生变化时进行监听。唯一的特殊情况是“它们都打开了吗”,如果是,按钮应该是“全部折叠”,如果不是,它应该是“全部展开”。

contentAreas.on({
    // whenever we open a panel, check to see if they're all open
    // if all open, swap the button to collapser
    show: function(){
        var isAllOpen = !contentAreas.is(':hidden');   
        if(isAllOpen){
            expandLink.text('Collapse All')
                .data('isAllOpen', true);
        }
    },
    // whenever we close a panel, check to see if they're all open
    // if not all open, swap the button to expander
    hide: function(){
        var isAllOpen = !contentAreas.is(':hidden');
        if(!isAllOpen){
            expandLink.text('Expand all')
            .data('isAllOpen', false);
        } 
    }
});​

编辑评论: 除非您点击“全部展开”按钮,否则保持“仅打开 1 个面板”实际上要容易得多。例子

于 2012-10-15T19:58:58.640 回答
21

其中很多似乎过于复杂。我通过以下方式实现了我想要的:

$(".ui-accordion-content").show();

JSFiddle

于 2015-11-28T00:30:56.463 回答
18

这是我的解决方案:

在实际项目中工作。

   $(function () {
    $("#accordion").accordion({collapsible:true, active:false});
    $('.open').click(function () {
        $('.ui-accordion-header').removeClass('ui-corner-all').addClass('ui-accordion-header-active ui-state-active ui-corner-top').attr({'aria-selected':'true','tabindex':'0'});
        $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
        $('.ui-accordion-content').addClass('ui-accordion-content-active').attr({'aria-expanded':'true','aria-hidden':'false'}).show();
        $(this).hide();
        $('.close').show();
    });
    $('.close').click(function () {
        $('.ui-accordion-header').removeClass('ui-accordion-header-active ui-state-active ui-corner-top').addClass('ui-corner-all').attr({'aria-selected':'false','tabindex':'-1'});
        $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
        $('.ui-accordion-content').removeClass('ui-accordion-content-active').attr({'aria-expanded':'false','aria-hidden':'true'}).hide();
        $(this).hide();
        $('.open').show();
    });
    $('.ui-accordion-header').click(function () {
        $('.open').show();
        $('.close').show();
    });
});

http://jsfiddle.net/bigvax/hEApL/

于 2013-04-05T16:38:06.293 回答
7

最后,我发现这是考虑到要求的最佳解决方案:

// Expand/Collapse all
$('.accordion-expand-collapse a').click(function() {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').next().slideToggle();
    $(this).text($(this).text() == 'Expand all' ? 'Collapse all' : 'Expand all');
    $(this).toggleClass('collapse');
    return false;
});

更新 JSFiddle 链接:http: //jsfiddle.net/ccollins1544/r8j105de/4/

于 2012-10-17T14:08:48.580 回答
3

我不相信你可以用手风琴做到这一点,因为它是专门设计的,保留了最多可以打开一个项目的属性。然而,即使您说您不想重新实现手风琴,您也可能高估了所涉及的复杂性。

考虑以下场景,其中您有一个垂直的元素堆栈,

++++++++++++++++++++
+     Header 1     +
++++++++++++++++++++
+                  +
+      Item 1      +
+                  +
++++++++++++++++++++
+     Header 2     +
++++++++++++++++++++
+                  +
+      Item 2      +
+                  +
++++++++++++++++++++

如果你很懒,你可以使用表格来构建它,否则,适当样式的 DIV 也可以工作。

每个项目块可以有一个类itemBlock。单击标题将导致 itemBlock 类的所有元素被隐藏($(".itemBlock").hide())。然后,您可以使用 jqueryslideDown()函数来展开标题下方的项目。现在你几乎已经实现了手风琴。

要展开所有项目,只需使用$(".itemBlock").show()或如果您想要动画,$(".itemBlock").slideDown(500)。要隐藏所有项目,只需使用$(".itemBlock").hide().

于 2012-10-11T15:55:02.537 回答
2

这是Sintheta转换为 jQuery 插件的代码: 将以下代码保存到 js 文件。

$.fn.collapsible = function() {
    $(this).addClass("ui-accordion ui-widget ui-helper-reset");
    var headers = $(this).children("h3");
    headers.addClass("accordion-header ui-accordion-header ui-helper-reset ui-state-active ui-accordion-icons ui-corner-all");
    headers.append('<span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-s">');
    headers.click(function() {
        var header = $(this);
        var panel = $(this).next();
        var isOpen = panel.is(":visible");
        if(isOpen)  {
            panel.slideUp("fast", function() {
                panel.hide();
                header.removeClass("ui-state-active")
                    .addClass("ui-state-default")
                    .children("span").removeClass("ui-icon-triangle-1-s")
                        .addClass("ui-icon-triangle-1-e");
          });
        }
        else {
            panel.slideDown("fast", function() {
                panel.show();
                header.removeClass("ui-state-default")
                    .addClass("ui-state-active")
                    .children("span").removeClass("ui-icon-triangle-1-e")
                        .addClass("ui-icon-triangle-1-s");
          });
        }
    });
}; 

在您的 UI 页面中引用它并调用类似于 jQuery 手风琴调用:

$("#accordion").collapsible(); 

看起来更干净,并避免将任何类添加到标记中。

于 2014-02-24T05:52:22.820 回答
2

我之前第二次 bigvax 评论,但你需要确保你添加

        jQuery("#jQueryUIAccordion").({ active: false,
                              collapsible: true });

否则你将无法在折叠后打开第一个手风琴。

    $('.close').click(function () {
    $('.ui-accordion-header').removeClass('ui-accordion-header-active ui-state-active ui-corner-top').addClass('ui-corner-all').attr({'aria-selected':'false','tabindex':'-1'});
    $('.ui-accordion-header .ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
    $('.ui-accordion-content').removeClass('ui-accordion-content-active').attr({'aria-expanded':'false','aria-hidden':'true'}).hide();
   }
于 2014-02-24T16:03:25.243 回答
1

试试这个jquery-multi-open-accordion,可能对你有帮助

于 2012-10-16T08:36:00.183 回答
0
Yes, it is possible. Put all div in separate accordion class as follows:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>

<script type="text/javascript">

        $(function () {
            $("input[type=submit], button")
        .button()
        .click(function (event) {
            event.preventDefault();
        });
            $("#tabs").tabs();
            $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: 0



            });
        });

function expandAll()
{
  $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: 0

            });

            return false;   
}

function collapseAll()
{
  $(".accordion").accordion({
                heightStyle: "content",

                collapsible: true,
                active: false



            });
            return false;
}
</script>



<div class="accordion">
  <h3>Toggle 1</h3>
  <div >
    <p>text1.</p>
  </div>
</div>
<div class="accordion">
  <h3>Toggle 2</h3>
  <div >
    <p>text2.</p>
  </div>
</div>
<div class="accordion">
  <h3>Toggle 3</h3>
  <div >
    <p>text3.</p>
  </div>
</div>
于 2014-01-15T11:10:50.277 回答
0

你可以试试这个轻量级的小插件。

它将允许您根据您的要求对其进行自定义。它将具有展开/折叠功能。

网址: http ://accordion-cd.blogspot.com/

于 2014-05-14T12:52:22.653 回答
0

我发现 AlecRust 的解决方案很有帮助,但我添加了一些东西来解决一个问题:当您单击单个手风琴展开它,然后单击按钮展开时,它们都会被打开。但是,如果您再次单击折叠按钮,之前展开的单个手风琴将不会折叠。

我使用了 imageButton,但您也可以将该逻辑应用于按钮。

/*** Expand all ***/
$(".expandAll").click(function (event) {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').next().slideDown();

    return false;
});

/*** Collapse all ***/
$(".collapseAll").click(function (event) {
    $('.accordion').accordion({
        collapsible: true,
        active: false
    });

    $('.accordion .ui-accordion-header').next().slideUp();

    return false;
});

此外,如果您在手风琴内有手风琴,并且您只想在第二层上展开 all,您可以添加一个查询:

/*** Expand all Second Level ***/
$(".expandAll").click(function (event) {
    $('.accordion .ui-accordion-header:not(.ui-state-active)').nextAll(':has(.accordion .ui-accordion-header)').slideDown();

    return false;
});
于 2014-06-18T13:33:55.467 回答
0

使用关于 Taifun 的示例,我进行了修改以允许展开和折叠。

... // 连接展开/折叠所有

var expandLink = $('.accordion-expand-all');

expandLink.click(function () {

$(".ui-accordion-content").toggle();
});
于 2017-04-21T05:34:21.537 回答
0

我尝试了老式版本,只是像许多这些旧答案一样调整 aria-* 和 CSS 属性,但最终放弃了,只是做了一个有条件的假点击。工作很漂亮':

HTML:

<a href="#" onclick="expandAll();"
  title="Expand All" alt="Expand All"><img
    src="/images/expand-all-icon.png"/></a>
<a href="#" onclick="collapseAll();"
  title="Collapse All" alt="Collapse All"><img
    src="/images/collapse-all-icon.png"/></a>

Javascript:

async function expandAll() {
  let heads = $(".ui-accordion-header");
  heads.each((index, el) => {
    if ($(el).hasClass("ui-accordion-header-collapsed") === true)
      $(el).trigger("click");
  });
}

async function collapseAll() {
  let heads = $(".ui-accordion-header");
  heads.each((index, el) => {
    if ($(el).hasClass("ui-accordion-header-collapsed") === false)
      $(el).trigger("click");
  });
}


(HTML 换行符放置在那些奇怪的地方,以防止演示文稿中出现空白。)

于 2019-12-08T02:46:01.763 回答
0

如果您对每个面板都是独立的感到满意,那么只需将每个面板放在它自己的手风琴中:

$(".accordion-panel").accordion({
            collapsible: true,
            multiple: true,
            active: 0
});

然后在 html 中,您可以将每个部分创建为自己的手风琴。

<div class="accordion-panel">
<h3 class="accordion-header">Section 1</h3>
    <div>
        <p>
        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.
        </p>
    </div>
</div>
<div class="accordion-panel">
<h3 class="accordion-header">Section 2</h3>
    <div>
        <p>
        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.
        </p>
    </div>
</div>
于 2021-03-10T18:47:39.793 回答