javascript - ejemplos - jquery accordion from scratch
jQuery UI Accordion Expand/Collapse All (12)
Al final, encontré que esta es la mejor solución teniendo en cuenta los requisitos:
// 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;
});
Estoy usando el acordeón jQuery UI (que no permite más de un elemento abierto a la vez ) en un proyecto. Usar el acordeón es apropiado ya que generalmente solo quiero un panel abierto a la vez.
Sin embargo, tengo que ofrecer un enlace "Expandir todos" que cambia a "Contraer todo" cuando se hace clic. No quiero personalizar la funcionalidad de acordeón casi idéntica en torno a este requisito, así que me gustaría un poco de JS que logre esto mientras se mantiene el componente de acordeón en uso.
Pregunta: ¿Qué JavaScript / jQuery se requiere para lograr esto mientras se usa el componente jQuery UI "Accordion" para alimentar la funcionalidad estándar?
Aquí hay un violín: http://jsfiddle.net/alecrust/a6Cu7/
Aquí está el código de convertido a un plugin jQuery: guarde el código debajo de un archivo 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");
});
}
});
};
Remítalo a su página de IU y llame de manera similar a jQuery accordian call:
$("#accordion").collapsible();
Se ve más limpio y evita que se agreguen clases al marcado.
El segundo comentario de bigvax es anterior pero debes asegurarte de agregar
jQuery("#jQueryUIAccordion").({ active: false,
collapsible: true });
de lo contrario, no podrás abrir el primer acordeón después de contraerlo.
$(''.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();
}
Encontré la solución de AlecRust bastante útil, pero agrego algo para resolver un problema: cuando haces clic en un solo acordeón para expandirlo y luego haces clic en el botón para expandirlo, todos se abrirán. Pero, si vuelve a hacer clic en el botón para colapsar, el acordeón único expandir antes no se colapsará.
He usado imageButton, pero también puedes aplicar esa lógica a los botones.
/*** 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;
});
Además, si tiene acordeones dentro de un acordeón y desea expandir todo solo en ese segundo nivel, puede agregar una consulta:
/*** 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;
});
Esta es mi solución:
Trabajando en proyecto real.
$(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();
});
});
Muchos de estos parecen ser demasiado complicados. Logré lo que quería con solo lo siguiente:
$(".ui-accordion-content").show();
No creo que puedas hacer esto con un acordeón, ya que está diseñado específicamente para preservar la propiedad y como máximo se abrirá un artículo. Sin embargo, aunque diga que no desea volver a implementar el acordeón, es posible que esté sobreestimando la complejidad involucrada.
Considere el siguiente escenario donde tiene una pila vertical de elementos,
++++++++++++++++++++
+ Header 1 +
++++++++++++++++++++
+ +
+ Item 1 +
+ +
++++++++++++++++++++
+ Header 2 +
++++++++++++++++++++
+ +
+ Item 2 +
+ +
++++++++++++++++++++
Si eres perezoso puedes construir esto usando una tabla, de lo contrario, los DIV adecuadamente diseñados también funcionarán.
Cada uno de los bloques de elementos puede tener una clase de itemBlock
. Al hacer clic en un encabezado se ocultarán todos los elementos de la clase itemBlock ( $(".itemBlock").hide()
). Luego puede usar la función jquery slideDown()
para expandir el ítem debajo del encabezado. Ahora ya casi has implementado el acordeón.
Para expandir todos los elementos, simplemente use $(".itemBlock").show()
o si lo quiere animado, $(".itemBlock").slideDown(500)
. Para ocultar todos los artículos, simplemente use $(".itemBlock").hide()
.
Puedes probar este pequeño complemento liviano.
Te permitirá personalizarlo según tu requerimiento. Tendrá funcionalidad Expand / Collapse.
Usando un ejemplo para Taifun, lo modifiqué para permitir la expansión y el colapso.
... // conectar la expansión / colapsar todo
var expandLink = $(''.accordion-expand-all'');
expandLink.click(function () {
$(".ui-accordion-content").toggle();
});
prueba este jquery-multi-open-accordion , podría ayudarte
Como se discutió en los foros de jQuery UI, no debe usar acordeones para esto.
Si quieres algo que luzca y actúe como un acordeón, está bien. Usa sus clases para diseñarlos e implementar la funcionalidad que necesites. Luego, agregar un botón para abrirlos o cerrarlos es bastante sencillo. Example
HTML
Al usar las clases jquery-ui, mantenemos nuestros acordeones parecidos a los acordeones "reales".
<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>
Haz rodar tus propios acordeones
En general, solo queremos que los encabezados de acordeón cambien el estado del siguiente hermano, que es su área de contenido. También hemos agregado dos eventos personalizados "show" y "hide", que engancharemos más tarde.
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;
});
Expandir / Contraer todo
Usamos un isAllOpen
boolean isAllOpen
para marcar cuando el botón ha sido cambiado, esto podría haber sido una clase o una variable de estado en un marco de plugin más grande.
expandLink.click(function(){
var isAllOpen = $(this).data(''isAllOpen'');
contentAreas[isAllOpen? ''hide'': ''show'']()
.trigger(isAllOpen? ''hide'': ''show'');
});
Cambia el botón cuando "todo está abierto"
Gracias a nuestros eventos personalizados "mostrar" y "ocultar", tenemos algo que escuchar cuando los paneles están cambiando. El único caso especial es "están todos abiertos", si es así, el botón debería ser "Contraer todo", si no debería ser "Expandir todo".
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);
}
}
});
Edite para comentarios: mantener "1 panel abierto solamente" a menos que presione el botón "Expandir todo" es mucho más fácil. Example
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>