Akordeon jQuery UI, który utrzymuje wiele sekcji otwartych?

93

Mogę być idiotą, ale jak zachować wiele sekcji w akordeonie jQuery UI? Wszystkie wersje demonstracyjne mają tylko jedną otwartą naraz ... Szukam zwijanego systemu menu.

Piechur
źródło
18
Spójrz na to jsfiddle.net/DkHyd
supersuphot
Cóż, twoja wtyczka jest po prostu idealna! Wielkie dzięki, stary!
SexyBeast

Odpowiedzi:

94

Zostało to pierwotnie omówione w dokumentacji interfejsu użytkownika jQuery dla Accordion :

UWAGA: Jeśli chcesz otworzyć wiele sekcji jednocześnie, nie używaj akordeonu

Akordeon nie pozwala na jednoczesne otwarcie więcej niż jednego panelu treści i wymaga to dużo wysiłku. Jeśli szukasz widżetu, który umożliwia otwarcie więcej niż jednego panelu treści, nie używaj tego. Zwykle można zamiast tego napisać kilka wierszy jQuery, coś takiego:

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

Lub animowane:

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

„Mogę być idiotą” - nie jesteś idiotą, jeśli nie czytasz dokumentacji, ale jeśli masz problemy, zwykle przyspiesza to znalezienie rozwiązania.

MvanGeest
źródło
9
To rozwiązanie nie obejmuje żadnej stylizacji na akordeon.
forresto
12
Co więcej, nie jest to w ogóle rozwiązanie tego problemu. Dokumentacja akordeonu i lista opcji, wydarzeń itp. Są po prostu słabe. I zamiast mówić użytkownikowi „jeśli nie mamy dla Ciebie opcji - nie używaj ich!” powinni powiedzieć „przepraszam, że nie ma jeszcze takiej opcji, ale zapraszamy wszystkich współpracowników, którzy dodają funkcjonalność do naszej wspaniałej wtyczki”
artgrohe
Cytowany przeze mnie tekst został usunięty z dokumentacji. Dodałem link do zarchiwizowanej wersji.
MvanGeest
1
Pamiętaj, że jQuery UI Accordion nie tylko tworzy rzeczywisty efekt akordeonu. Dodaje również wiele znaczników dostępności dla czytników ekranu.
Brian
2
To nie ma sensu. Akordeon może mieć otwarte wszystkie fałdy, jeśli ramiona muzyka są daleko od siebie, wszystkie fałdy zamknięte, jeśli połówki instrumentu są razem lub coś pomiędzy. Jeśli słowa coś znaczą, sterowanie interfejsem oprogramowania harmonijki powinno zezwalać na dowolną kombinację paneli otwartych i zamkniętych.
birdus
119

Dość proste:

<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>
2upmedia
źródło
1
Działało świetnie. Dodałem, create: function(event) { $(event.target).accordion( "activate", false ); }aby zacząć upadł.
forresto
2
Niesamowite. Cieszę się, że ci się udało. :) Lubię, gdy wszystko jest tak proste, jak to tylko możliwe.
2upmedia
7
w jquery-ui 1.10, aby rozpocząć zwinięcie, zamiast create: function(event) { $(event.target).accordion( "activate", false ); }ciebie ustaw opcję:{active: false}
damko
16
(facepalm) osobny akordeon dla każdego bloku.
Paul Annekov
2
Oto jsFiddle, którego użyłem do przetestowania. Jsfiddle.net/txo8rx3q/1 Dodałem również trochę CSS, aby zatrzymać otwartą sekcję akordeonu, która wygląda na wybraną po jej rozwinięciu
Matthew Lock
78

Opublikowałem to w podobnym wątku, ale pomyślałem, że może to mieć znaczenie również tutaj.

Osiągnięcie tego za pomocą jednej instancji jQuery-UI Accordion

Jak zauważyli inni, Accordionwidżet nie ma opcji interfejsu API, aby zrobić to bezpośrednio. Jeśli jednak z jakiegoś powodu musisz użyć widgetu (np. Utrzymujesz istniejący system), możesz to osiągnąć, używając beforeActivateopcji obsługi zdarzeń, aby obalić i emulować domyślne zachowanie widgetu.

Na przykład:

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

Zobacz demo jsFiddle

Boaz
źródło
6
Dzięki! To najlepsze rozwiązanie, ponieważ nie potrzebujesz żadnych zmian w całym istniejącym środowisku.
artgrohe
Wymaga interfejsu użytkownika jQuery w wersji 1.9.0+ (Drupal 7 utknął z
wersją
1
Wierzę, że zmieniła się aktywna klasaui-accordion-header-active
Tim Vermaelen
zadziałało dla mnie świetnie, minimalna ilość refaktoryzacji :-)
Darkloki
dobre rozwiązanie, jedynym problemem jest to, że to rozwiązanie nie będzie miało opcji ikony :-)
Tachyony
21

A może prostsze?

<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>
Roman Gudkov
źródło
To miło imho. Łatwe rozwiązanie i rozwiązało problemy, które miałem podczas wykonywania dużych zestawów elementów akordeonu. Zaskakująco zainicjowanie dużego zestawu akordeonów sprawdza się dobrze. Dzięki!
Code Novitiate
14

Zrobiłem wtyczkę jQuery, która ma taki sam wygląd jak jQuery UI Accordion i może utrzymywać otwarte wszystkie karty \ sekcje

można go znaleźć tutaj

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

działa z tym samym znacznikiem

<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>

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

AKTUALIZACJA: wtyczka została zaktualizowana, aby obsługiwać domyślną opcję aktywnych kart

AKTUALIZACJA: ta wtyczka jest obecnie przestarzała.

Anas Nakawa
źródło
Świetne rozwiązanie.
Trimantra Software Solution
6

Właściwie przez jakiś czas szukałem w Internecie rozwiązania tego problemu. Zaakceptowana odpowiedź daje dobrą odpowiedź „z książki”. Ale nie chciałem tego zaakceptować, więc szukałem dalej i znalazłem to:

http://jsbin.com/eqape/1601/edit - przykład na żywo

Ten przykład pobiera odpowiednie style i dodaje żądaną funkcjonalność w tym samym czasie, wraz z miejscem na zapis, dodając własną funkcjonalność po każdym kliknięciu nagłówka. Pozwala również na umieszczanie wielu elementów DIV pomiędzy „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();

Kod 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>`
Donovan
źródło
5

Znalazłem trudne rozwiązanie. Wywołajmy tę samą funkcję dwa razy, ale z innym identyfikatorem.

Kod JQuery

$(function() {
    $( "#accordion1" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
    $( "#accordion2" ).accordion({
        collapsible: true, active: false, heightStyle: "content"
    });
});

Kod 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>
SpritsDracula
źródło
2
Lepiej jest iść z pojedynczym selektorem w oparciu o classsugestie innych, to oznacza, że nie powtarzasz się ( DRY )
Scotty.NET
4

Proste, utwórz wiele akordeonowych div, z których każdy reprezentuje jeden tag kotwicy, na przykład:

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

Dodaje trochę znaczników. Ale działa jak profesjonalista ...

Azeem
źródło
4

Prosty: aktywuj akordeon dla klasy, a następnie twórz z nim elementy div, takie jak wielokrotne instancje akordeonu.

Lubię to:

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/

Giovan Cruz
źródło
1
Wypróbowałem wszystkie odpowiedzi w wątku i to działa najlepiej. Dzięki najnowszym jquery i jqueryUI jest teraz wiele problemów ze stylizacją innych rozwiązań. Oto aktualizacja z 2017 roku jsfiddle.net/rambutan2000/eqbbgb7g
Geordie
@Geordie Cieszę się, że pomogło.
Giovan Cruz
2

Po prostu nazwij każdą sekcję akordeonu jako jego własny akordeon. active: n będzie równe 0 dla pierwszego (więc wyświetli się), a 1, 2, 3, 4 itd. dla reszty. Ponieważ każdy z nich jest własnym akordeonem, wszystkie będą miały tylko 1 sekcję, a reszta zostanie zwinięta, aby rozpocząć.

$('.accordian').each(function(n, el) {
  $(el).accordion({
    heightStyle: 'content',
    collapsible: true,
    active: n
  });
});
Funkodebat
źródło
Zauważ, że zostało to już zasugerowane w odpowiedzi 2upmedia poniżej
Boaz
2

Jeszcze prościej, niech będzie oznaczony w atrybucie class każdego znacznika li i jquery zapętli każdy li w celu zainicjowania akordeonu.

Mikey
źródło
1

Bez akordeonu jQuery-UI można to zrobić po prostu:

<div class="section">
  <div class="section-title">
    Section 1
  </div>
  <div class="section-content">
    Section 1 Content: Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
  </div>
</div>

<div class="section">
  <div class="section-title">
    Section 2
  </div>
  <div class="section-content">
    Section 2 Content: Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
  </div>
</div>

I js

$( ".section-title" ).click(function() {
    $(this).parent().find( ".section-content" ).slideToggle();
});

https://jsfiddle.net/gayan_dasanayake/6ogxL7nm/

Gayan Dasanayake
źródło
0

otwórz jquery-ui - *. js

odnaleźć $.widget( "ui.accordion", {

znaleźć w _eventHandler: function( event ) {środku

zmiana

var options = this.options,             active = this.active,           clicked = $( event.currentTarget ),             clickedIsActive = clicked[ 0 ] === active[ 0 ],             collapsing = clickedIsActive && options.collapsible,            toShow = collapsing ? $() : clicked.next(),             toHide = active.next(),             eventData = {
                oldHeader: active,
                oldPanel: toHide,
                newHeader: collapsing ? $() : clicked,
                newPanel: toShow            };

do

var options = this.options,
    clicked = $( event.currentTarget),
    clickedIsActive = clicked.next().attr('aria-expanded') == 'true',
    collapsing = clickedIsActive && options.collapsible;

    if (clickedIsActive == true) {
        var toShow = $();
        var toHide = clicked.next();
    } else {
        var toShow = clicked.next();
        var toHide = $();

    }
    eventData = {
        oldHeader: $(),
        oldPanel: toHide,
        newHeader: clicked,
        newPanel: toShow
    };

przed active.removeClass( "ui-accordion-header-active ui-state-active" );

dodać if (typeof(active) !== 'undefined') {i zamknąć}

cieszyć się

Alex
źródło
-1

Po prostu użyj funkcji jquery each ();

$(function() {
    $( ".selector_class_name" ).each(function(){
        $( this ).accordion({
          collapsible: true, 
          active:false,
          heightStyle: "content"
        });
    });
});
czarna Mamba
źródło