Super Menú V0.002

He estado trabajando en un script para poder crear menús desplegables a partir de arrays. Ayer terminé lo que yo llamo la versión 0.002 de dicho script y quisiera compartirla con ustedes. Me gustaría aclarar que el propósito de compartirla no es distribuirla, por lo menos no todavía. El propósito en compartirla es más bien en cierta forma liberar el código y permitir que otros usuarios aprendan de él, pero también abrir un flujo de información a través del cual se estén haciendo sugerencias sobre lo que habría que mejorar, o cambiar en el script para lograr una mejora en el desempeño. También cabe aclarar que en proyectos abiertos al publico en general, como en sitios web, no es recomendable su uso ya que es un asesino de todo intento de accesibilidad. Esto por la simple razón de que Javascript es absolutamente necesario para poder crear el menú. Por tal motivo, recomiendo que si se usa, sea solo en ambientes que tenemos ‘controlados’ o en los que sabemos que los usuarios necesariamente tendrán javascript disponible y activado, por ejemplo, en una aplicación AIR, en el área administrativa de un sitio a la que sabemos que se accede con javascript disponible y activado, a apps locales que se usan con dispositivos que tienes javascript disponible y activado y situaciones similares.

La lógica detrás del script es muy sencilla. Si sigues regularmente el blog, habrás notado que me gusta hacer scripts sencillos y en cierta forma demostrar que los scripts no tiene por que alcanzar un nivel de complejidad que resulte confuso incluso para el autor de script. El script consiste, por el momento, de un constructor y un objeto. El constructor es una función llamada Desplegable. El trabajo de esta función es crear una serie de listas (elementos ul) anidadas tomando como base un array el cual se le pasa como primer parámetro. La función por el momento toma tres parámetros, dos de los cuales son opcionales. Como la función es un constructor y tratada como tal, la llamada no puede ser directa, hay que crear una instancia del constructor, por lo que una llamada a la función se vería más o menos así:

var miMenu = new Desplegable(estructura, direccion, contenedor);

En donde:

estructura: es el array sobre el cual se basa el menú.

direccion:por ahora toma solo un valor, ‘vertical’,  y sirve para especificar la dirección en la que el menú es creado.

contenedor: Es el id del elemento en el cual queremos que se cree nuestro menú.

de modo que si quiero crear un menú y que este sea agregado dentro de un div con id=’cabecera’, la llamada sería la siguiente:

var miMenu = new Desplegable(estructura, 'vertical', 'cabecera');

Notar que el último parámetro es el id y no una referencia al elemento en el cual queremos que se agregue el menú. Pasar una referencia del tipo:

var cabecera = document.getElementById('cabecera');
var miMenu = new Desplegable(estructura, direccion, cabecera);

Daría un resultado inesperado que podría causar destrozos en tu proyecto.

El único parámetro que por el momento es obligatorio es el primero, el cual pasa la estructura del array que queremos tomar como base para crear las listas anidadas. El segundo parámetro, si no se especifica, toma como por defecto el valor ‘vertical’. Recordar que este parámetro por ahora solo puede tomar el valor ‘vertical’. El tercer parámetro, si no se especifica, toma como valor por defecto el elemento body (etiqueta <body>). Es poco recomendable que no se especifique este parámetro ya que puede causar efectos inesperados como poner el menú hasta el final de la página, después incluso del pié de página.

El otro componente es un objeto llamado sM. Este se encarga de dos cosas:

1)Carga el CSS para el menú
2)Controla el plegado y desplegado de los sub-menús.

Este elemento es reciclado, es decir, ya lo tenía entre mis curiosidades. Cabe aclarar que este objeto no es de mi propia autoría, fue más bien creado en uno de los capítulos de DHTML utopia. El propósito al incluir este objeto fue demostrar que es sencillo crear nuestro propio objeto para controlar el plegado y desplegado de los menús de la forma en que queramos. Siempre y cuando nos aseguremos de que dicho objeto llame una función de Desplegable llamada aggCSS(), la cual agrega el CSS al menú.

La razón del porque aggCSS es llamada por el objeto que controla el plegado y desplegado de los sub-menús, es por que si en determinado momento quisiéramos crear nuestro propio objeto para controlar el plegado y desplegado de los menús interiores, sería útil llamar solo a la función Desplegable, analizar el código que genera y ver el árbol que genera. (El CSS nos impediría ver ese aábol.) Poder ver el árbol que genera es una gran ventaja ya que con simplemente ver la estructura de las listas anidadas te puedes dar una idea sobre como controlarlas.

Bueno, sin más, veamos como se hace una llamada real al menú. Como lo que me interesa es simplemente demostrar la creación del array, no tomaré en cuenta los dos últimos parámetros, dejándolos que tomen sus valores por defecto.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 <title>Untitled</title>
 <script type="text/javascript" src="sM.js">

 </script>
</head>
<body>
<script type="text/javascript">

 estructura = [
 'acerca de->about.html',
 'bio->bio.html',
 [
 'proyectos',
 [
 'CSS',
 'menus->menuscss.html',
 'galerias->galeriascss.html',
 'layouts->layoutscss.html'
 ],
 [
 'javascript',
 'menus->menusjs.html',
 'galerias->galeriasjs.html',
 'animaciones->animacionesjs.html'
 ],
 'php->proyectosphp.html'
 ],
 'contacto->contacto.html',
 [
 'sitios amigos',
 'jseros->http://www.jseros.com/',
 'panino5001->http://www.disegnocentell.com.ar/',
 'I\'m Buzu->https://imbuzu.wordpress.com/'
 ]
 ]
 var miMenu = new Desplegable(estructura);
 sM.menuRef = miMenu;
 sM.init();
</script>

</body>
</html>

Algunas cosas a notar:

El array es un array multidimencional donde cada array anidado representa un ul anidado.

Para especifcar la url a la que apunta el elemento del menú, se pone “->” seguido directamente de la url a la que apunta dicho elemento.

notar sM.menuRef = miMenu. Aquí lo que estamos haciendo es pasandole a sM una referencia al menú para que sepa que aggCSS activar.

Notar la llamada a sM.init().

Creo que el código se explica por si solo. Puedes ver un ejemplo en vivo en:

http://www.p-freeweb.com/outside/javascript/scripts/supermenu/v0_002/sMV0_002Demo.html

También puedes ver el Javascript en:

http://www.p-freeweb.com/outside/javascript/scripts/supermenu/v0_002/sMv0_002.js

Nota: El menú aun no es ni versión 1, por lo que hay muchas cosas que se pueden mejorar aun, espero sus comentarios. El menú ha sido provado en FF 3.5. Tomando en cuenta que su uso no es recomendable para proyectos públicos, soporte para IE no es una prioridad.