jQuery UI acordeão que mantém várias seções abertas?

93

Eu posso ser um idiota, mas como você mantém várias seções do acordeão do jQuery UI abertas? Todas as demos têm apenas uma aberta por vez ... Estou procurando um sistema de tipo de menu que pode ser recolhido.

andador
fonte
18
Olhe para jsfiddle.net/DkHyd
supersuphot
Bem, seu plugin é simplesmente perfeito! Muito obrigado, cara!
SexyBeast

Respostas:

94

Isso foi discutido originalmente na documentação do jQuery UI para Accordion :

NOTA: Se você quiser que várias seções sejam abertas ao mesmo tempo, não use um acordeão

Um acordeão não permite que mais de um painel de conteúdo seja aberto ao mesmo tempo, e é preciso muito esforço para fazer isso. Se você está procurando um widget que permite a abertura de mais de um painel de conteúdo, não o use. Normalmente, pode ser escrito com algumas linhas de jQuery, algo assim:

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

Ou animado:

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

"Eu posso ser um idiota" - Você não é um idiota se não ler a documentação, mas se estiver tendo problemas, geralmente acelera a busca de uma solução.

MvanGeest
fonte
9
Esta solução não faz nenhum estilo de acordeão.
forresto de
12
Além disso, essa não é a solução para a questão. A documentação do acordeão e a lista de opções, eventos, etc. são simplesmente precárias. E em vez de dizer ao usuário "se não tivermos as opções para você - não use!" eles devem dizer "desculpe, mas não há opção para isso ainda, mas agradecemos qualquer contribuidor que adicione funcionalidade ao nosso ótimo plugin"
artgrohe
O texto que citei foi removido da documentação. Eu adicionei um link para uma versão arquivada.
MvanGeest,
1
Lembre-se de que o jQuery UI Accordion faz mais do que criar o efeito de acordeão real. Ele também adiciona muitas marcações de acessibilidade para leitores de tela.
Brian
2
Isso não faz sentido. Um acordeão pode ter todas as pregas abertas se os braços do músico estiverem afastados, todas as pregas fechadas se as metades do instrumento estiverem juntas, ou algo no meio. Se as palavras significam alguma coisa, o controle da IU do software de acordeão deve permitir qualquer combinação de painéis abertos e fechados.
birdus
119

Bem simples:

<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
fonte
1
Funcionou muito bem. Eu adicionei create: function(event) { $(event.target).accordion( "activate", false ); }para começar recolhido.
forresto de
2
Impressionante. Que bom que funcionou para você. :) Gosto de manter as coisas o mais simples possível.
2upmedia
7
em jquery-ui 1.10, para começar recolhido, em vez de create: function(event) { $(event.target).accordion( "activate", false ); }definir a opção:{active: false}
damko
16
(facepalm) acordeão separado para cada bloco.
Paul Annekov
2
Aqui está o jsFiddle que usei para testá-lo jsfiddle.net/txo8rx3q/1 Também adicionei algum CSS para impedir que uma seção de acordeão aberta pareça selecionada quando é expandida
Matthew Lock
77

Postou isso em um tópico semelhante, mas pensei que poderia ser relevante aqui também.

Conseguir isso com uma única instância de jQuery-UI Accordion

Como outros notaram, o Accordionwidget não tem uma opção de API para fazer isso diretamente. No entanto, se por algum motivo você precisar usar o widget (por exemplo, se estiver mantendo um sistema existente), é possível fazer isso usando a beforeActivateopção do manipulador de eventos para subverter e emular o comportamento padrão do widget.

Por exemplo:

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

Veja uma demonstração do jsFiddle

Boaz
fonte
6
Obrigado! Esta é a melhor solução, pois você não precisa de nenhuma mudança em todo o ambiente existente.
artgrohe
Requer jQuery UI 1.9.0+ (Drupal 7 está preso com 1.8.7)
Capi Etheriel
1
Eu acredito que a classe ativa mudouui-accordion-header-active
Tim Vermaelen
funcionou muito bem para mim, quantidade mínima de refatoração :-)
Darkloki
boa solução, o único problema é que esta solução não aceita a opção de ícone :-)
Tachyons
20

Ou ainda mais simples?

<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
fonte
Isso é bom imho. Solução fácil e que resolveu problemas que eu estava tendo com o desempenho de grandes conjuntos de itens de sanfona. Surpreendentemente, inicializar um grande conjunto de acordeões funciona bem. Obrigado!
Código do Noviciado de
14

Eu fiz um plugin jQuery que tem a mesma aparência do jQuery UI Accordion e pode manter todas as guias \ seções abertas

Você pode encontrá-lo aqui

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

funciona com a mesma marcação

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

Código 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
});

ATUALIZAÇÃO: o plugin foi atualizado para suportar a opção de abas ativas padrão

ATUALIZAÇÃO: Este plugin está obsoleto.

Anas Nakawa
fonte
Excelente solução de sempre.
Trimantra Software Solution
6

Na verdade, estava pesquisando na internet por uma solução para isso por um tempo. E a resposta aceita dá a boa resposta "pelo manual". Mas eu não queria aceitar isso, então continuei pesquisando e encontrei o seguinte:

http://jsbin.com/eqape/1601/edit - Exemplo ao vivo

Este exemplo puxa os estilos adequados e adiciona a funcionalidade solicitada ao mesmo tempo, completa com espaço para adicionar sua própria funcionalidade em cada clique no cabeçalho. Também permite que vários divs estejam entre os "h3" s.

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

Código 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
fonte
5

Eu encontrei uma solução complicada. Vamos chamar a mesma função duas vezes, mas com id diferente.

Código JQuery

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

Código 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>
SpritsDrácula
fonte
2
É melhor você ir com um único seletor baseado no classcomo sugerido por outros, isso significa que você não se repete ( DRY )
Scotty.NET
4

Simples, crie vários div de acordo com cada um representando uma tag âncora como:

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

Adiciona alguma marcação. Mas funciona como um profissional ...

Azeem
fonte
4

Simples: ative o acordeão para uma classe e, em seguida, crie divs com isso, como instâncias múltiplas de acordeão.

Como isso:

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
fonte
1
Tentei todas as respostas do tópico e funcionou melhor. Com o jquery e o jqueryUI mais recentes, existem muitos problemas de estilo com outras soluções agora. Aqui está a atualização de 2017 jsfiddle.net/rambutan2000/eqbbgb7g
Geordie
@Geordie Fico feliz que tenha ajudado.
Giovan Cruz
2

Basta chamar cada seção do acordeão como seu próprio acordeão. ativo: n será 0 para o primeiro (assim será exibido) e 1, 2, 3, 4, etc. para o resto. Como cada um é seu próprio acordeão, todos terão apenas 1 seção e o restante será recolhido para iniciar.

$('.accordian').each(function(n, el) {
  $(el).accordion({
    heightStyle: 'content',
    collapsible: true,
    active: n
  });
});
Funkodebat
fonte
Observe que isso já foi sugerido na resposta da 2upmedia abaixo
Boaz
2

Ainda mais simples, tenha-o rotulado em cada atributo de classe da tag li e tenha jquery para fazer um loop por cada li para inicializar o acordeão.

Mikey
fonte
1

Sem o acordeão jQuery-UI, pode-se simplesmente fazer isso:

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

E js

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

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

Gayan Dasanayake
fonte
0

abrir jquery-ui - *. js

encontrar $.widget( "ui.accordion", {

encontrar _eventHandler: function( event ) { dentro

mudança

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

para

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

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

adicionar if (typeof(active) !== 'undefined') { e fechar}

desfrutar

alex
fonte
-1

Você apenas usa a função jquery each ();

$(function() {
    $( ".selector_class_name" ).each(function(){
        $( this ).accordion({
          collapsible: true, 
          active:false,
          heightStyle: "content"
        });
    });
});
Mamba negra
fonte