En este tutorial aprenderemos a crear nuestro propio menú desplegable basado en jQuery. Lo haremos partiendo de cero y explicándolo como siempre paso a paso, de forma que todos podamos comprender cómo plantear el problema y buscar una solución sencilla y efectiva.

Autor: Adrián Mato

Hola! Soy diseñador, programador web y cofundador de la startup Cokidoo, desarrollamos aplicaciones web a gran escala y comercio electrónico, aplicaciones para móviles y advertising. Puedes seguirme através de mi twitter y ver algunos de mis themes en Themeforest. También soy aficionado a la fotografía.
Descarga Demostración

Introducción: ¿Qué vamos a hacer?

Retomamos los tutoriales relacionados con javascript y jQuery de la mano de este control en forma de menú desplegable.

Al contrario que otros controles de este tipo, para desplegar este control, el usuario sólo tendrá que pasar el ratón por encima, en lugar de hacer click. Este será el aspecto final del control a crear:

Vista previa

La idea es que las distintas opciones sean mostradas en formato lista (<ul>), de forma que cada elemento de la lista sea un enlace que te traslade a una nueva sección en la que aparezca marcada la nueva opción seleccionada.

El control no necesitará hacer el cambio entre sección actualmente activa y la seleccionada, ya que eso se controlaría a la hora de generar la salida html en la lógica de programación (PHP, Java, Python… o lo que quiera que uséis).

Actualización: Por cierto… veo que algunas personas no lo han entendido bien: estamos imprimiendo una salida HTML limpia, por tanto los robots y rastreadores de Google y derivados, podrán indexar y seguir perfectamente todas esas opciones de nuestro menú.

¡Vamos a por el primer paso del tutorial!

Paso 1: La estructura HTML

Como acostumbramos a realizar en nuestros tutoriales, mantendremos una estructura sencilla, intentando que sea vistosa pero sobretodo clara a la hora de comprender qué estamos haciendo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="es-ES">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Cómo crear un menú de pestañas elegante en jQuery</title>
    <link rel="stylesheet" href="css/main.css" type="text/css" media="screen" />
</head>
<body>
    <div class="wrapper">
        <h1>Creando un menú desplegable en jQuery</h1>
        <ul class="dropdown">
			<li class="active">Visualizando: <span>Tutoriales</span></li>
			<li class="first"><a href="#">Recursos</a></li>
			<li><a href="#">Inspiración</a></li>
			<li><a href="#">Contacto</a></li>
			<li class="last"><a href="#">Ver más...</a></li>
		</ul>
    </div>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="main.js"></script>
</body>
</html>

Esto es lo que deberíamos tener actualmente:

Vista previa paso 1

Básicamente lo único relevante de este paso es comprender que estamos aplicando la clase de CSS “dropdown” a nuestra lista, con la que estaremos advirtiendo a nuestro futuro código javascript que será un control del tipo desplegable.

Vamos pues a darle un poco de estilo al ejemplo antes de ponernos con la lógica en javascript…

Paso 2: Aplicando estilo con CSS a nuestro menú desplegable

En este caso, el código CSS es muy básico y se centra principalmente en el aspecto visual del control de menú desplegable que estamos creando:

@CHARSET "UTF-8";
/*
Author: Adrian Mato
Author URI: http://web.ontuts.com
*/

/******* GENERAL RESET *******/
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td {
    border:0pt none;
    font-family:inherit;
    font-size:100%;
    font-style:inherit;
    font-weight:inherit;
    margin:0pt;
    padding:0pt;
    vertical-align:baseline;
}
body{
    line-height: 1em;
    font-size: 14px;
    font-family: Arial, Helvetica, sans-serif;
    margin: 0pt;
    cursor: default;
    color: #fff;
    background: #262626 url("bg.png") repeat scroll 0 0;
}
table{
    border-collapse: separate;
    border-spacing: 0pt;
}
strong{
    font-weight: 700;
}
caption, th, td{
    font-weight:normal;
    text-align:left;
}
blockquote:before, blockquote:after, q:before, q:after{
    content:"";
}
blockquote, q{
    quotes:"" "";
}
pre{
    font-family: Arial, Helvetica, sans-serif;
}
input{
    border: 0;
    margin: 0;
    font-family: Arial, Helvetica, sans-serif;
}
textarea{
    font-family: Arial, Helvetica, sans-serif;
    color: #888888;
    padding: 7px 3px 0 4px;
    font-size: 11px;
}
select{
    font-size: 11px;
    color: #888888;
    background: #fff;
    font-family: Arial, Helvetica, sans-serif;
    border: 1px solid #CAD2CE;
}
ul{
    list-style: none;
    list-style-type: none;
    list-style-position: outside;
}
a{
    cursor: pointer;
    color: #ece6bd;
    text-decoration: underline;
    outline: none !Important;
}
html,body{
    height:100%;
}
.clear{
    clear: both;
    height: 0;
    visibility: hidden;
    display: block;
    line-height: 0;
}
.clearfix{
    overflow: hidden;
}
.italic{
    font-style: italic;
}
/******* /GENERAL RESET *******/

/******* GENERAL *******/
h1{
    color: #fff;
    font-size: 26px;
    line-height: 3em;
}
h2{
    line-height: 2em;
    margin-top: 30px;
    margin-bottom: 20px;
    color: #e4e1cd;
}
.wrapper{
    width: 982px;
    margin: 0pt auto;
    padding-top: 10px;
}
/******* /GENERAL *******/

/******* CONTENT *******/
h3{
    line-height:1em;
    vertical-align:middle;
    height:48px;
    padding:10px 10px 10px 52px;
    font-size:32px;
    color:#E4E1CD;
}
/******* /CONTENT *******/

/******* MENU *******/
ul.dropdown{
	width: 200px;
	border: 1px solid #000;
	border-radius: 5px;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	background: #1a1a1a;
	margin-top: 2em;
}
ul.dropdown li{
	display: none;
	font-size: 12px;
}
ul.dropdown li.active{
	display: block;
	color: #8c8c8c;
	font-size: 14px;
	padding: 12px;
	color: #555;
	border-top: 1px solid #313131;
	border-radius: 4px;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;
}
ul.dropdown li.active span{
	background: transparent url("dropdown.png") no-repeat scroll right center;
	padding-right: 24px;
	color: #8c8c8c;
}
ul.dropdown li a{
	display: block;
	text-decoration: none;
	padding: 8px 8px 8px 10px;
	background: #1e1e1e;
	border-bottom: 1px solid #171717;
}
ul.dropdown li.last a{
	border:0;
}
ul.dropdown li.first a{
	border-top: 3px solid #131313;
}
ul.dropdown li a:hover{
	background: #232323;
	color: #fff;
	padding-left: 11px;
}
/******* /MENU *******/

La clase dropdown será con la que identificaremos el control y sobre la cual aplicaremos el resto de propiedades a los distintos elementos.

Así pues todos los elementos de la lista compartirán estilo excepto la clase active la cual aparecerá siempre en el primer puesto de la lista, y será la que identifique el elemento actualmente seleccionado / activo.

Este es el aspecto que presentará ahora nuestro control:

Vista previa paso 2

Como habréis podido comprobar, ahora no se están mostrando los elementos de la lista, salvo el elemento activo. Sólo necesitamos crear la lógica para que se muestren / oculten a nuestro antojo via javascript…

¡Vamos a ello!

Paso 3: Añadiendo interacción con javascript mediante jQuery

Repasemos qué es lo que queremos de nuestro control en forma de menú despegable antes de aplicar la interacción:

  • Mostrar opciones al pasar el ratón por encima.
  • Ocultar opciones al mover el ratón de encima.
  • Reutilizable para tener múltiples controles en una misma página.

Con esto en mente, necesitaremos identificar (mediante selectores de jQuery) los elementos de clase “dropdown” para reconocerlos como controles de menú desplegable.

Antes de explicar la parte de los eventos, echemos un vistazo al código final:

//variable global para controles dropdown
var menu = $("ul.dropdown");

//control de eventos
$(this.document).ready(function(){
	menu.mouseover(function(){
		displayOptions($(this).find("li"));
	});
	menu.mouseout(function(){
		hideOptions($(this));
	});
})

//funcion que MUESTRA todos los elementos del menu
function displayOptions(e){
	e.show();
}
//funcion que OCULTA los elementos del menu
function hideOptions(e){
	e.find("li").hide();
	e.find("li.active").show();
}

El código como podéis comprobar es relativamente sencillo, y en el podemos ver la asignación de los eventos “al pasar por encima” y “al quitar el ratón de encima”, los cuales llaman a las funciones:

  • displayOptions(): Muestra todos los elementos de la lista inicialmente ocultos al pasar el ratón por encima.
  • hideOptions(): Oculta todos los elementos de la lista, y luego vuelve a mostrar el elemento activo.

La razón por la que mostramos nuevamente el elemento activo es porque el selector de jQuery que estamos empleando está ocultando todos los elementos de la lista, entre los que se incluye el activo, pero deseamos que se mantenga visible.

Antes de dar por finalizado el tutorial, me gustaría resaltar otro detalle del código anterior: la función find(), mediante la cual localizamos los elementos del control que está recibiendo los eventos.

Siempre que programes controles reutilizables, trata de trabajar con referencias al objeto activo, de esta forma podrás reutilizarlos o crear plugins de forma realmente sencilla.

Podríamos estar utilizando selectores de jQuery genéricos pero recordad: queremos que nuestro control pueda aparecer en más de una ocasión en una misma página, por tanto trabajamos con referencias al objeto activo, en lugar de a todos los objetos que contengan la clase de CSS dropdown.

Con todo ello, generar un plugin apartir de este planteamiento sería realmente trivial. Si bien no lo hemos hecho en este tutorial, sí que hemos explicado anteriormente cómo crear plugins en jQuery, echadle un vistazo que es realmente útil.

Reflexión final

Una vez más vuelvo a insistir en lo de siempre: con un poco de curiosidad y ganas por profundizar en lo que nos interesa podemos -en este caso- crear controles dinámicos en javascript de forma realmente sencilla.

Lo más importante es tener claro qué es lo que queremos que haga nuestro control (sus eventos, etc…) y luego buscar la mejor solución posible a cada uno de esos requisitos ya sea con jQuery u otras librerías javascript que manejemos.

Espero que os haya resultado útil y… ¡Nos vemos en el próximo artículo!

¿Necesitas desarrollar un proyecto web o para móviles? ¡Estamos disponibles!

Visitar Cokidoo

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnológicos centrados en redes sociales y aplicaciones web, aplicaciones móviles y consultoría web y bases de datos.

Somos jóvenes, inquietos, versátiles, apasionados por la innovación y enfocados en las nuevas tecnologías. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnológica.

Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicación (21 comentarios)

¿Te ha gustado esta publicación? ¡Puedes compartir tu opinión con todos nosotros! Simplemente pincha aquí mismo.

Se habían hecho esperar… pero vuelven los tutoriales de javascript and company ^__^

Adrián, te juro que no es mi intención trollear :-) , pero, aunque el artículo está muy bien, no me convence nada esta solución en si porque no es nada accesible y los spiders no pueden seguir los enlaces.

Me parece mucha mejor solución esta, que es prácticamente CSS y con casi nada de javascript (de hecho si desactivas javascript con el web developer sigue funcionando):

http://www.htmldog.com/articles/suckerfish/dropdowns/example/bones3.html

Simplemente es mi intención aportar otras soluciones al mismo problema. :-)

@Pablo ya sabes que no molestan nunca los comentarios constructivos ;)

Pero te estás equivocando, realmente esos enlaces sí que son “cliqueables” por los spiders y bots rastreadores, estamos generando una salida HTML totalmente limpia: una lista con enlaces. La muestra más clara la tienes en la primera imagen que mostramos en el paso 1 :)

Por cierto, el ejemplo que has mostrado está genial pero eso es un menú para secciones y subsecciones, realmente este está planteado como un dropdown a modo de “select”, no con intención de barra de navegación al uso.

@adri, cuando te refieres a un “select”, ¿hablas de por ejemplo en las futuras Experiencias traducidas de Erasmusu.com el desplegable para cambiar de idioma? Jejeje…

Y sí, claro que es crawleable, sólo que en el ejemplo no ha puesto links a ningún sitio. Pero se ve claro que el html generado lleva los links, que es lo que verá el crawler.

Los valores href=”#˝ no dejan de ser valores y enlaces, tenedlo en cuenta. Supongo que de ahí ha surgido la duda de Pablo.

Reyvolsam

Pues muy interesante el articulo, no se programar en JQuery y este ejemplo esta muy bien ademas de que el resultado queda super bien.
Desde hoy sigo este blog amigo, espero mas sobre JQuery o relacionados…

¡¡¡SAludos!!

Cierto, me lié yo solito por no pararme a verlo con calma. :-)

Un fallo de usabilidad de este tipo de menús es que el menú debe permanecer en pantalla hasta que se hace clic fuera de él.

Si el menú desaparece simplemente por mover el ratón fuera, puede hacerse muy complicado hacer clic en una opción…

También recomendaría que el menú no se desplegase hasta no hacer clic en él.

En fin, espero que no te tomes a mal mi critica. :)

Saludos

@Daniel, también puedes asignarle un delay al desplegable, para que desaparezca después de un tiempo si el usuario lo abandona.

Ejemplo (deplegable de idiomas): http://www.cafebabel.es/article/33863/pompidou-arte-contemporaneo-europa-este-historia.html

Sobre lo del click, depende. Por ejemplo en algunos Menús, como el de http://www.erasmusu.com, si cliqueas encima, te lleva a una sección distinta que las del resto del desplegable, por lo que no tendría sentido.

Para el resto de casos, como el de Cafe Babel, personalmente, también prefiero el click. No hay nada que moleste más que mover el ratón por la pantalla y que “algo salte”.

@Daniel No te preocupes por las críticas, faltaría más!

Personalmente no estoy de acuerdo en que sea un fallo de seguridad, es una opción tan o más válida que el desplegarlos con click. A mí personalmente para este tipo de controles me gusta más que se autodesplieguen, sin hacer pensar al usuario… y además si te fijas hemos dejado un padding lo suficientemente grande como para que el usuario oculte el menú sin querer o sin llegar a ser tedioso.

Pero como todas estas cosas, hasta que no lo pruebas con usuarios en tiempo real, no sabrás si realmente estás en lo cierto o no :)

Excelente, lo vamos a aplicar en nuestro sitio, espero y publiquen pronto la actualizacion.
Saludos desde CANCUN, MEXICO

Nicolas

Hola amigo, excelente menu, tengo una consulta, yo al utilizar el menu, cuando se despliega se me tira para abajo todos los contenidos que tengo. Te paso el ejemplo del site que te estoy comentando..
http://www.ppiova.com/
Saludos
Nicolas.

Joseph

Hola, me gusta este tutorial. Pero pienso q deberias limitar el estilo css para los elementos especificos del dropdown. Por medio de un id o clases, para q al implementarlo en algun sitio no estropee los estilos que ya se tienen. SALU2

sickboy

bueno con un show(‘fast’) creo que queda fantástico, me dio varias buenas ideas, muchas gracias por este muy buen tutorial

Davo

Hola amigo, soy nuevo en esto, weno, estoy en clases de desarrollo web, y pues nuestra profesora nos mando a maquetizar y crear un sitio web, estuve viendo tu menu desplegable, lo agregue a una pagina, pero no logro crear mas menus como ese horizontalmente, para usarlo como mi menu principal, quiciera usar mas menues desplegables para mi pagina pero no lo logro. por ejemplo, kisiera ponerlo donde va: inicio, somos, etc…. porfas, disculpa por mi ignorancia, pero apenas estoy empezando en el mundo web.

ZeusAlfred

Wey no mames gracias… buen aporte…. le gusto a mi jefe… gracias…. me salvaste el trabajo ok sigue asi……..

Oscar

Hola, posiblemente sobrevole el tutorial rapidamente, pero el archivo main.css, esta incluido en algun lugar ? O es parte de JQuery?

Blanca

Hola

Esta genial el ejemplo. Tengo una pregunta y es como puedo cambiar que el menú al desplegarse se vea por encima de la tabla con lo que contenga un flash, imagenes,,, y no me desplace lo demás hacia abajo.

Gracias.

Gabriel
Emanuel

¿Por que al incluir el archivo Javascript y Jquery arriba dentro de las etiquetas (Precisamente debajo de la deja de funcionar?

Añade Tu Comentario