简体   繁体   English

jQuery UI 手风琴展开/折叠全部

[英]jQuery UI Accordion Expand/Collapse All

I'm using the jQuery UI Accordion (which does not allow more than one item open at a time ) on a project.我在一个项目中使用jQuery UI Accordion (它不允许一次打开多个项目)。 Using accordion is appropriate since I usually do only want one panel open at a time.利用手风琴,因为通常只想要一次在一个面板打开为宜。

However, I need to offer an "Expand All" link which switches to "Collapse All" when clicked.但是,我需要提供一个“全部展开”链接,单击时会切换到“全部折叠”。 I don't want to custom write near-identical accordion functionality around this one requirement, so I'd like some JS that will achieve this whilst keeping the Accordion component in use.我不想围绕这一要求自定义编写几乎相同的手风琴功能,所以我想要一些 JS 来实现这一点,同时保持手风琴组件的使用。

Question: What JavaScript/jQuery is required to achieve this whilst still using the jQuery UI "Accordion" component to power the standard functionality?问题:需要什么 JavaScript/jQuery 才能实现这一点,同时仍然使用 jQuery UI“Accordion”组件来支持标准功能?

Here's a fiddle: http://jsfiddle.net/alecrust/a6Cu7/这是一个小提琴: http : //jsfiddle.net/alecrust/a6Cu7/

As discussed in the jQuery UI forums, you should not use accordions for this. 正如jQuery UI 论坛中所讨论的,您不应该为此使用手风琴。

If you want something that looks and acts like an accordion, that is fine.如果你想要一些看起来和动作都像手风琴的东西,那很好。 Use their classes to style them, and implement whatever functionality you need.使用他们的类来设计它们,并实现您需要的任何功能。 Then adding a button to open or close them all is pretty straightforward.然后添加一个按钮来打开或关闭它们是非常简单的。 Example例子

HTML HTML

By using the jquery-ui classes, we keep our accordions looking just like the "real" accordions.通过使用 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>​

Roll your own accordions卷起你自己的手风琴

Mostly we just want accordion headers to toggle the state of the following sibling, which is it's content area.大多数情况下,我们只希望手风琴标题切换以下兄弟的状态,即它的内容区域。 We have also added two custom events "show" and "hide" which we will hook into later.我们还添加了两个自定义事件“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;
});

Expand/Collapse All展开/折叠全部

We use a boolean isAllOpen flag to mark when the button has been changed, this could just as easily have been a class, or a state variable on a larger plugin framework.我们使用布尔值isAllOpen标志来标记按钮何时被更改,这可以很容易地成为一个类,或者一个更大的插件框架上的状态变量。

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

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

Swap the button when "all open" “全部打开”时交换按钮

Thanks to our custom "show" and "hide" events, we have something to listen for when panels are changing.多亏了我们自定义的“显示”和“隐藏”事件,当面板发生变化时,我们可以听到一些东西。 The only special case is "are they all open", if yes the button should be a "Collapse all", if not it should be "Expand all".唯一的特殊情况是“它们都打开了吗”,如果是,按钮应该是“全部折叠”,如果不是,它应该是“全部展开”。

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);
        } 
    }
});​

Edit for comment: Maintaining "1 panel open only" unless you hit the "Expand all" button is actually much easier.编辑评论:除非您点击“全部展开”按钮,否则保持“仅打开 1 个面板”实际上要容易得多。 Example例子

A lot of these seem to be overcomplicated.其中许多似乎过于复杂。 I achieved what I wanted with just the following:我通过以下方式实现了我想要的:

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

JSFiddle JSFiddle

This my solution:这是我的解决方案:

Working in real project.在实际项目中工作。

   $(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/ http://jsfiddle.net/bigvax/hEApL/

In the end I found this to be the best solution considering the requirements:最后,我发现这是考虑到要求的最佳解决方案:

// 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;
});

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

I don't believe you can do this with an accordion since it's specifically designed preserve the property that at most one item will be opened.我不相信你可以用手风琴做到这一点,因为它是专门设计的,保留了最多打开一件物品的特性。 However, even though you say you don't want to re-implement accordion, you might be over estimating the complexity involved.然而,即使您说不想重新实现手风琴,您也可能高估了所涉及的复杂性。

Consider the following scenario where you have a vertical stack of elements,考虑以下场景,其中您有一个垂直的元素堆栈,

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

If you're lazy you could build this using a table, otherwise, suitably styled DIVs will also work.如果你很懒惰,你可以使用表格来构建它,否则,适当样式的 DIV 也可以工作。

Each of the item blocks can have a class of itemBlock .每个项目块都可以有一个itemBlock类。 Clicking on a header will cause all elements of class itemBlock to be hidden ( $(".itemBlock").hide() ).单击标题将导致隐藏类 itemBlock 的所有元素( $(".itemBlock").hide() )。 You can then use the jquery slideDown() function to expand the item below the header.然后,您可以使用 jquery slideDown()函数展开标题下方的项目。 Now you've pretty much implemented accordion.现在您几乎已经实现了手风琴。

To expand all items, just use $(".itemBlock").show() or if you want it animated, $(".itemBlock").slideDown(500) .要展开所有项目,只需使用$(".itemBlock").show()或者如果你想要它动画, $(".itemBlock").slideDown(500) To hide all items, just use $(".itemBlock").hide() .要隐藏所有项目,只需使用$(".itemBlock").hide()

Here's the code by Sinetheta converted to a jQuery plugin: Save below code to a js file.这是由Sinetheta转换为 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");
          });
        }
    });
}; 

Refer it in your UI page and call similar to jQuery accordian call:在您的 UI 页面中引用它并调用类似于 jQuery 手风琴调用:

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

Looks cleaner and avoids any classes to be added to the markup.看起来更干净并避免将任何类添加到标记中。

I second bigvax comment earlier but you need to make sure that you add我之前第二次发表了 bigvax 评论,但您需要确保添加

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

otherwise you wont be able to open the first accordion after collapsing them.否则你将无法在折叠它们后打开第一个手风琴。

    $('.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();
   }

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

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>

You can try this lightweight small plugin.你可以试试这个轻量级的小插件。

It will allow you customize it as per your requirement.它将允许您根据您的要求对其进行自定义。 It will have Expand/Collapse functionality.它将具有展开/折叠功能。

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

I found AlecRust's solution quite helpful, but I add something to resolve one problem: When you click on a single accordion to expand it and then you click on the button to expand, they will all be opened.我发现 AlecRust 的解决方案非常有用,但我添加了一些东西来解决一个问题:当您单击单个手风琴展开它,然后单击按钮展开时,它们都会被打开。 But, if you click again on the button to collapse, the single accordion expand before won't be collapse.但是,如果再次单击折叠按钮,则不会折叠之前展开的单个手风琴。

I've used imageButton, but you can also apply that logic to buttons.我使用过 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;
});

Also, if you have accordions inside an accordion and you want to expand all only on that second level, you can add a query:此外,如果您在手风琴内有手风琴并且您只想在第二级展开所有,您可以添加一个查询:

/*** 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;
});

Using an example about for Taifun, I modified to allow expand and collapse.使用有关 Taifun 的示例,我进行了修改以允许展开和折叠。

... // hook up the expand/collapse all ... // 连接展开/折叠全部

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

expandLink.click(function () {

$(".ui-accordion-content").toggle();
});

I tried the old-fashioned version, of just adjusting aria-* and CSS attributes like many of these older answers, but eventually gave up and just did a conditional fake-click.我尝试了老式版本,只是像许多这些旧答案一样调整 aria-* 和 CSS 属性,但最终放弃了,只是做了一个有条件的假点击。 Works a beaut':效果很好':

HTML: 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: 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");
  });
}


(The HTML newlines are placed in those weird places to prevent whitespace in the presentation.) (HTML 换行符放置在那些奇怪的地方以防止演示文稿中出现空格。)

If you are ok with each panel being independent then just put each panel in it's own accordion:如果您认为每个面板都是独立的,那么只需将每个面板放在它自己的手风琴中:

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

Then in the html you can create each section as it's own accordion.然后在 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM