Crear un menú estilo acordeón con jQuery
Antes de arrancar, quiero mostrarles lo que vamos a construir. Para ello nada mejor que ver el demo haciendo click en el link de la derecha o bien descargar los archivos (deberán contar con un servidor local para probarlo).
En el siguiente tutorial me voy a enfocar principalmente en el código javascript del framework jQuery, dejando de lado la explicación PHP.
El menú que vamos a desarrollar tiene la ventaja de dejar abierta la sub botonera cuando nos encontramos dentro del mismo grupo de links. Para entender esto mejor, vayan al demo, ingresen en Posts » Agregar Post y vean que al recargar la página, la sección Posts queda desplegada.
Estructura de carpetas y archivos

Tenemos un index.php en donde vamos a llamar a la hoja de estilos, al framework jQuery y escribir nuestro menú en HTML. Allí también incluiremos a través de PHP las distintas secciones del sitio utilizando los parametros “p” (de página) y “sec” (de sección) por el método GET.
Las páginas, que las llamaremos “p” (posts.php, categorias.php, multimedia.php, etc.) las colocaremos en el raíz del sitio; las secciones, “sec” (agregar-post.php, listar-posts.php, etc.) estarán guardadas dentro una carpeta llamada “paginas” y bajo otra llamada como el “p” que le corresponde.
Para comprender mejor veamos el siguiente ejemplo: agregar-post.php es el “sec” que pertenece al “p” posts.php, entonces estará alojado en /paginas/posts/agregar-post.php. Ésto lo pueden observar en la imagen superior.
Escribiendo el menú en HTML y PHP
<div id="menu">
<h3>Administrar</h3>
<ul>
<li><span <?php if($p == "posts"){echo 'class="current"';} ?>><a href="javascript:void(0);" id="link-posts">Posts</a></span>
<ul>
<li><a href="?p=posts&sec=agregar-post" class="add">Agregar</a></li>
<li><a href="?p=posts&sec=listar-posts" class="list">Listar</a></li>
</ul>
</li>
<li><span <?php if($p == "categorias"){echo 'class="current"';} ?>><a href="javascript:void(0);" id="link-categorias">Cateogrías</a></span>
<ul>
<li><a href="?p=categorias&sec=agregar-categoria" class="add">Agregar</a></li>
<li><a href="?p=categorias&sec=listar-categorias" class="list">Listar</a></li>
</ul>
</li>
<li><span <?php if($p == "multimedia"){echo 'class="current"';} ?>><a href="javascript:void(0);" id="link-multimedia">Multimedia</a></span>
<ul>
<li><a href="?p=multimedia&sec=agregar-galeria-imagenes" class="add">Agregar galería de imágenes</a></li>
<li><a href="?p=multimedia&sec=listar-galeria-imagenes" class="list">Listar galería de imágenes</a></li>
<li><a href="?p=multimedia&sec=agregar-galeria-video" class="add">Agregar galería de video</a></li>
<li><a href="?p=multimedia&sec=listar-galeria-video" class="list">Listar galería de video</a></li>
</ul>
</li>
<li><span <?php if($p == "usuarios"){echo 'class="current"';} ?>><a href="javascript:void(0);" id="link-usuarios">Usuarios</a></span>
<ul>
<li><a href="?p=usuarios&sec=agregar-usuario" class="add">Agregar</a></li>
<li><a href="?p=usuarios&sec=listar-usuarios" class="list">Listar</a></li>
</ul>
</li>
<li><span <?php if($p == "opciones"){echo 'class="current"';} ?>><a href="javascript:void(0);" id="link-opciones">Opciones</a></span>
<ul>
<li><a href="?p=opciones&sec=opcion-lectura" class="bullet">Lectura</a></li>
<li><a href="?p=opciones&sec=opcion-escritura" class="bullet">Escritura</a></li>
<li><a href="?p=opciones&sec=opcion-discusion" class="bullet">Discusión</a></li>
<li><a href="?p=opciones&sec=opcion-permalinks" class="bullet">Permalinks</a></li>
</ul>
</li>
</ul>
</div>Vamos a seguir está lógica:
Dentro de un div con el id “menu” (referencia para CSS y jQuery) tendremos una lista desordenada. Dentro de cada <li> vamos a tener un <span> que contendrá el nombre de la página, y seguido a éste otra lista desordenada con las subpaginas.
Podrán observar que dentro de cada <span> comparo si $p (url en la que estoy) es igual a la página principal de ese <li>, si lo es imprimo la clase “current”.
Escribiendo el menú jQuery
El siguiente código lo vamos a encontrar antes de cerrar la etiqueta html <head>. En la primer línea llamamos al framework jQuery alojado en Google y luego escribiremos el menú, el cual iré explicando paso a paso más abajo.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ //Menu desplegable $("#menu ul li ul").hide(); $("#menu ul li span.current").addClass("open").next("ul").show(); $("#menu ul li span").click(function(){ $(this).next("ul").slideToggle("slow").parent("li").siblings("li").find("ul:visible").slideUp("slow"); $(this).toggleClass("open"); $(this).parent("li").siblings("li").find("span").removeClass("open"); }); }); </script>
Primero escribimos:
$(document).ready(function(){
Estamos diciendo que cuando el documento este listo, ejecutemos todo lo siguiente.
Luego tenemos estas dos líneas:
$("#menu ul li ul").hide(); $("#menu ul li span.current").addClass("open").next("ul").show();
La primera es la que se encarga de esconder todos los <ul> childrens, estos son los que están a continuación de cada <span> en nuestra estructura HTML.
La segunda línea dice: A todos los <span> que están dentro del <div id="menu"><ul><li> y tengan la clase “current” agregales la clase “open”, busca el <ul> que le sigue y abrilo. Ésta línea nos sirve para que cuando estemos en la sección “Agregar Post” el menú “Posts” quede abierto mostrandonos las demás opciones que tenemos.
Ahora vamos a analizar el extracto de código que se encarga del acordeón.
$("#menu ul li span").click(function(){ $(this).next("ul").slideToggle("slow").parent("li").siblings("li").find("ul:visible").slideUp("slow"); $("#menu ul li").find("span").removeClass("open"); $(this).addClass("open"); });
Lo que estamos diciendo básicamente es que cuando se hace click en un <span> se ejecuta una función que hace:
- A ésto (el
<span>que hicimos click), buscale el siguiente<ul>, a éste hacele un slideToggle() (es decir, si está abierto cerralo y si esta cerrado abrilo, todo con una bonita transición del estilo slideUp/slideDown); luego subimos un nivel hasta el elemento padre del<ul>: el<li>, buscamos los hermanos (siblings) del<li>y los cerramos a todos. - Buscamos todos los
<span>que existan dentro de<div id="menu"><ul><li>y les sacamos la clase “Open”. - A ésto (el
<span>que hicimos click) le agregamos la clase “Open”.
Y eso es todo.
Conclusión
Como verán, jQuery es una librería muy flexible que nos permite sin saber mucho de javascript, realizar complementos muy interesantes.
Para éste ejemplo, y más si son nuevos con jQuery, les recomiendo que presten mucha atención al funcionamiento de parent() y siblings() y traten de entender bien cuales son sus funciones. Relean el listado en donde explico con palabras lo que más arriba escribo en jQuery ( la función que realiza el acordeón) las veces necesarias hasta entenderla del todo.
Por otro lado, si bien lo he probado en varios navegadores, no lo hice en todos. Si ven algo raro me avisan en los comentarios. Y cualquier duda también!

8 Comentarios »
Patricio
28.10.09, 2:46 pm
Muy bueno Negro, muy claro. Están buenos estos tutoriales porque uno aprende JQuery desde el mismo uso que le va dando…
Por cierto, muy buena forma de organizar los archivos ;)
Patricio
28.10.09, 3:07 pm
Una idea que se me ocurrió…
Para la URL pasás dos variables, la sec que es lo que incluye el contenido que vas a usar, y otra llamada p que al parecer solo la usás para definir si la navegación está abierta o no. Considerando que sec está nombrada en algo así como accion-categoria (agregar-post, agregar-multimedia, etc), podrías directamente pasar la variable sec y para verificar el menu al que corresponde tomás la segunda parte de la variable.
Con un explode en PHP, separás la variable en los guiones, y verificás el segundo valor que te retorne (que sería post, categoría, multimedia, etc). Así te ahorrarías de pasar dos variables en la URL.
Germán Ferrari
28.10.09, 4:14 pm
Totalmente Pato! Muy buena la idea ;) Además el hecho de que te haya entendido significa también que estoy aprendiendo más de PHP, jeje.
Por otra parte… creo que fuiste vos quién me enseño esa forma de organizar archivos… no? Digo porque en el comentario anterior no entendí si era ironía o no lo de “muy buena forma de organizar los archivos” :P
Saludos!
Patricio
28.10.09, 8:15 pm
Joya, ya sos un casi PHP Gurú (?). Animate y probá, y si te sale actualizás el post ;)
Y sí, lo dije porque es el Panel que te programé yo :P
Germán Aroca
16.05.10, 8:00 pm
Buscando menús Web me encontré con este post y me ha encantado el menú así que le haré unos cambios y lo implementaré en un proyecto.
Se agradece el aporte tocayo
Saludos..
Miguel Colmenares
10.07.10, 5:49 pm
Hola, es un muy buen menú, lo he implementado y funciona perfecto, pero me ha surgido una duda, si quisiera agregar un tercer nivel por ejemplo después de “agregar” en el menú Posts.
¿como haría para que se despliegue nuevamente el menú?
No se mucho de Jquery y no se me ocurren alternativas para solucionarlo.
Gracias por la ayuda que me puedan prestar.
Han enlazado esta entrada:
[...] This post was mentioned on Twitter by Pinceladas da Web, Eduardo N. Fortes ✔. Eduardo N. Fortes ✔ said: RT @germanferrari: Crear un menú estilo acordeón con jQuery http://bit.ly/10udxP <- muy groso! [...]
[...] Crear un meú estilo acordeón con jQuery [...]