Moderador del foro: ZorG  
Foro uCoz » Ayuda a los webmasters » Configuración del diseño » Menús (escribimos aquí sobre la cosa)
Menús
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 31 | 7:02 PM
Menú con tabs con CSS, jQuery y Mootools

Esos menúes tipo tabs ó con subniveles tanto horizontales como verticales, son muy útiles al momento de desplegar grandes cantidades de navegación sin ser invasivos con el espacio. Puedes arquitecturar toda la estructura de tu sitio de manera tal que el usuario pueda encontrar fácilmente la información que desee, sólo con ir descubriendo con el mouse las subsecciones que están contenidas dentro del árbol general de navegación.

Por suerte hacer estos tipos de menúes es bastante fácil: basta con tener claro cómo funcionan los menúes con listas e ir anidando unas dentro de otras; incluso sólo con CSS es suficiente para hacerla funcionar, pero lamentablemente el peor browser de la historia universal (IE6) no soporta pseudo-classes en selectores que no sean links (<a>). Así que lo mejor y que más soporte cross-browser nos entrega es utilizar Javascript en este proceso. Y qué mejor que utilizar jQuery ó Mootools, 2 de los frameworks con los que me gusta jugar.

En este artículo veremos el proceso para crear un menú con tabs y cómo hacerlo funcionar mediante CSS y con la ayuda de Javascript.

Como mencionaba, un menú con tabs se compone básicamente de listas anidadas sobre otras listas. El HTML sería el siguiente:

Quote
<ul id="menu">
<li><a href="#">Uno</a></li>
<li class="cabeza"><a href="#">Dos</a>
<ul>
<li><a href="#">Dos.Uno</a></li>
<li><a href="#">Dos.Dos</a></li>
<li><a href="#">Dos.Tres</a></li>
</ul>
</li>
<li><a href="#">Tres</a></li>
<li class="cabeza"><a href="#">Cuatro</a>
<ul>
<li><a href="#">Cuatro.Uno</a></li>
<li><a href="#">Cuatro.Dos</a></li>
</ul>
</li>
</ul>

Ver ejemplo del HTML

Si el mundo fuera hermoso y no existiera IE6, nos bastaría con un poco de CSS y selectores avanzados de atributos para hacerlo funcionar:

Quote
ul {
list-style: none;
}
ul li {
float: left;
width: 100px;
text-align: center;
}
li.cabeza>ul {
display: none;
}
li.cabeza:hover>ul {
display: block;
}

Ver ejemplo con CSS

Para mejorar el manejo del despliegue de los subniveles, le coloqué una class="cabeza" a cada elemento de lista (<li>) que contenga cada nuevo subnivel. Ahora es más fácil diferenciarlas con CSS ó Javascript, como mostraré a continuación. Primero, con jQuery:

Quote
$(document).ready(function(){
// primero escondemos todos los subniveles
$('li.cabeza > ul').hide();
// luego le agregamos el evento de mouseover y mouseout mediante hover de jQuery
$('li.cabeza').hover(
function() {
$('ul', this).show();
},
function() {
$('ul', this).hide();
}); });

Ver ejemplo jQuery

Muy simple. Ahora, con Mootools (1.11):

Quote
window.addEvent('domready', function() {
// creamos una variable 'list' que será el selector <li> con class="cabeza", ya que la usaremos más de una vez.
var list = $$('li.cabeza');
// luego escondemos cada <ul> que esté contenido dentro de li.cabeza mediante display: none
list.getElement('ul').setStyle('display', 'none');
// ahora agregamos los eventos de mouseenter y mouseout respectivos
list.each(function(el) {
el.addEvent('mouseenter', function(){
$(this).getElement('ul').setStyle('display', 'block');
});
el.addEvent('mouseleave', function(){
$(this).getElement('ul').setStyle('display', 'none');
});
});
});

Ver ejemplo Mootools

Finalmente si usas un browser bueno, cualquier de los 3 métodos funcionará igual; viene de ti implementarlo de la mejor forma para que tus usuarios que aún usen IE6 para visitar tu sitio puedan disfrutar de una buena navegación y del contenido que ofrece.


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 32 | 2:36 PM
Cómo hacer un menú vertical contráctil

Partimos de que tenemos un menú formado por una lista no ordenada (ol) de links categorizados bajo distintos apartados:

Apartado 1
o sección 1
o sección 2
o sección 3
Apartado 2
o sección 4
o sección 5
Apartado 3
o sección 6
o sección 7
o sección 8

El código HTML es el siguiente

Quote
<ul>
<li>Apartado 1
<ul>
<li>sección 1</li>
<li>sección 2</li>
<li>sección 3</li>
</ul>
</li>
<li>Apartado 2
<ul>
<li>seccion 4</li>
<li>sección 5</li>
</ul>
</li>
<li>Apartado 3
<ul>
<li>sección 6</li>
<li>sección 7</li>
<li>sección 8</li>
</ul>
</li>
</ul>


Nos vamos a ahorrar el asignar identificadores y andar enviándolos a la función Javascript que nos maneje el asunto a base de manejarnos puramente usando el DOM. Cada vez que se llame a la función Javascript enviaremos como único parámetro el propio elemento que la llama usando la sentencia this que lo que hace es referenciarse o indicarse a sí mismo el objeto que dispara el evento.

Si a nuestra función la llamamos Menu(elementoQueLlama) y debemos pasarle el propio elemento que la llama como argumento lo haremos usando this

Quote
<ul>
<li onclick="Menu(this)"> Apartado 1
<ul> ...


Y en nuestra función Javascript haremos lo siguiente: lo que queremos es mostrar u ocultar la lista anidada (ul) dentro del elemento del Apartado 1

Quote
<ul>
<li onclick="Menu(this)"> Apartado 1
<ul> ... // ◄ -- este elemento queremos mostrar u ocultar


Aprovechando que todos los elementos donde hacer click y los elementos a ser mostrados u ocultados van a tener un patrón estructural común encontraremos al elemento sobre el cual actuar a partir del elemento que activa la llamada a la función y que se referencia a sí mismo mediante this
Observamos que el ul que queremos abrir/cerrar está anidado dentro del elemento la que llama a la función, es decir, es un nodo dentro del elemento la que llama a la función.

• Nodo ul

o Nodo la con la llamada a Menu(this)

 Nodo ul a mostrar u ocultar

El nodo ul a mostrar u ocultar (el tercero del esquema) es un nodo hijo del nodo la con la llamada a Menu(this) (el segundo del esquema).

El nodo li con la llamada a Menu(this) (el segundo del esquema) es el nodo padre del nodo ul a mostrar u ocultar.

Si a la función Javascript Menu(elementoQueLlama) le hacemos una llamada enviando la referencia del propio elemento que la llama como argumento con Menu(this) tendremos dentro de la función la referencia al elemento que la llamó dentro de la variable elementoQueLlama

Quote
function Menu(elementoQueLlama){
// elementoQueLlama guarda ahora al elemento que llamó a la función
}


¿Y cuál es el elemento que queremos abrir o cerrar? El elemento ul que es un nodo hijo de elementoQueLlama
Vamos a encontrar, lo primero, los elementos ul contenidos en elementoQueLlama usando el método del DOM getElementsByTagName()

Quote
elementosUlEnelementoQueLlama = elementoQueLlama.getElementsByTagName('ul')

Ahora tenemos en la variable elementosUlEnelementoQueLlama la lista de ul's que se encuentren dentro del elemento que llamó al script guardados en un array de 0 o más elementos (según lo que se haya encontrado dentro del elemento al que se le hizo click).

Este elemento ul que buscamos será el primer ul definido en elementoQueLlama así que accedemos a él mediante su posición en el array devuelto

Quote
elementoQueQueremos = elementosUlEnelementoQueLlama[0];

Bueno, pues ya tenemos localizado el elemento que queremos abrir o cerrar en elementoQueQueremos. Ahora no tenemos más que asignarle la propiedad CSS display a none o a block. Vamos a usar los operadores condicionales para hacerlo:

Quote
elementoQueQueremos.style.display = elementoQueQueremos.style.display == 'none' ? 'block' : 'none' ;

Estupendo, no nos queda más que probarlo. Agregamos como atributo el manejador de eventos a los elementos la que deban encargarse de activar el script con la llamada a la función onclick="Menu(this)"

Quote
<li onclick="Menu(this)">Apartado 1 ...

¿Y si queremos anidar otro nivel ?
¿Qué pasa si queremos poner otro nivel de profundidad a nuestro menú? Pues sencillamente, que hará cosas raras.

Apartado 1
o sección 1
 Sección 1-b
o sección 2
o sección 3
Apartado 2
o sección 4
o sección 5
Apartado 3
o sección 6
o sección 7
o sección 8

Nos encontramos con que al intentar abrir o cerrar Sección 1 lo que se activa además es el Apartado 1, es decir, el nodo padre de Sección 1.

¿Por qué sucede esto?

Pues es muy sencillo. El elemento la padre (Apartado 1) abarca a todo su contenido; eso incluye la lista anidada y la lista anidada dentro de ésta. De hecho en cualquier parte del área de Apartado 1 (eso incluye márgenes) se nos disparará la llamada a la función en el momento de hacer click. Así que cuando hacemos click en Sección 1 su elemento padre también está recogiendo el evento.

Lo que haremos entonces es cambiar el manejador de eventos a otro elemento que sólo afecte al texto en donde se deba hacer click.

Vamos a meter el texto clickable dentro de un tag strong. Podemos usar cualquier otro tag; si no queremos agregarle ningún sentido semántico a ese texto podemos usar un span pero en este ejemplo usaremos strong.

Quote
<ul>
<li><strong onclick="Menu(this)">Apartado 1</strong>
<ul>
<li><strong onclick="Menu(this)">sección 1 </strong>
<ul>
<li>seccion 1-b</li>
</ul>
</li>
...


Macanudo, ahora el evento sólo afecta al texto en donde se hará click y no al resto de elementos hijos o padres.

Pero … ahora el script no funciona :-(

Pasa que estamos usando esta referencia

Quote
elementosUlEnelementoQueLlama = elementoQueLlama.getElementsByTagName('ul')

y ahora el elementoQueLlama ya no es el la, si no un tag strong hijo de este la y éste strong no contiene a ningún elemento ul, por lo tanto nos devuelve un array (lista) vacío.

La forma de solucionarlo es referenciar al li que nos interesa (el que teníamos referenciado en un principio). Para ello nada más fácil que indicar que queremos al padre del elementoQueLlama

Quote
elLiQueQueremos = elementoQueLlama.parentNode

Resumiendo el único cambio que debemos hacer a nuestra línea es este:

Quote
elementosUlEnelementoQueLlama = elementoQueLlama.parentNode.getElementsByTagName('ul')

¡Listo! Ya tenemos de nuevo referenciado nuestro elemento para abrir o cerrar. Eso sí, algo importante es que el script funciona en base a un patrón estructural del menú; eso quiere decir que todos los elementos deben estar estructurados de la misma manera, o sea, llamando a la función desde algún tag que implique sólo al texto en donde hacer click y que ese tag sea hijo directo (no nieto) del la padre del ul con el que queramos interactuar.

Quote
function Menu(elementoQueLlama){
elementosUlEnelementoQueLlama = elementoQueLlama.parentNode.getElementsByTagName('ul');
elementoQueQueremos = elementosUlEnelementoQueLlama[0];
elementoQueQueremos.style.display = elementoQueQueremos.style.display == 'none' ? 'block' : 'none' ;
}


Ahora bien, eso ha estado bien para describir el ejemplo. Yo le pondría unos nombres más sencillos a esas variables :-P y podríamos reducir a sólo dos líneas así

Quote
function Menu(el){
elemento = el.parentNode.getElementsByTagName('ul')[0]
elemento.style.display = elemento.style.display == 'none' ? 'block' : 'none'
}



Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 33 | 1:42 PM
Menú y galería de imágenes tipo slide con CSS y HTML

Nosotros hemos visto ya como se puede simular algunos efectos dinámicos empleando solo CSS y HTML. En este post les proponemos simular un slide de imágenes para un menú vertical u horizontal o para una galería de imágenes. A continuación desarrollaremos el ejemplo con los códigos correspondientes explicados, de forma que se pueda comprender el funcionamiento y aplicarlo en la forma que se crea más conveniente.

Este efecto es más sencillo que los casos mostrados anteriormente, y nos muestra que para conseguir algunos efectos interesantes no es necesario utilizar códigos complejos, emplear scripts en otros lenguajes o utilizar animaciones. Basta con conocer los principios básicos de la maquetación y el potencial de las hojas de estilo en cascada y emplear un poco de imaginación.

Mientras preparamos los archivos para que puedan descargarlos y mostrar el ejemplo terminado para que lo puedan ver en funcionamiento, pueden copiar los códigos que se encuentran en el artículo.

Principio de funcionamiento
El principio en el cual está basado este ejemplo, es mucho más simple que en los casos del menú desplegable y la galería de imágenes que hemos descrito en otros artículos, y se basa en el comportamiento de las capas flotantes y la utilización de la pseudoclase :hover.

La pseudoclase :hover se utiliza para modificar los parámetros de un elemento cuando el puntero pasa sobre él. Normalmente se le utiliza para que se modifique un enlace y cambie de color o cambie el subrayado cuando el puntero se posa sobre él. Pero también se pueden modificar otras propiedades, como las dimensiones (width y height, ancho y altura) de una imagen o una capa.

Ejemplo
Puedes ver el ejemplo en funcionamiento aquí: slide con CSS y HTML, y también puedes descargarte los archivos del ejemplo.

Los códigos HTML y CSS
En primer lugar les dejaremos el código HTML:

Quote
<html>
<head>
<title>Ejemplo</title>
<link rel="stylesheet" href="estilo.css" type="text/css" />
</head>
<body>
<div id="izquierda">
<ul id="menu">
<li><a href="#"><img src="img/1.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/2.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/3.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/4.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/5.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/6.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/7.jpg" alt="#" title="#" /></a></li>
</ul>
</div>
<div class="derecha">
<ul id="menu2">
<li><a href="#"><img src="img/21.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/22.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/23.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/24.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/25.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/26.jpg" alt="#" title="#" /></a></li>
<li><a href="#"><img src="img/27.jpg" alt="#" title="#" /></a></li>
</ul>
</div>
<div class="derecha">
<ul id="galeria">
<li><img src="img/31.jpg" alt="#" title="#" /></li>
<li><img src="img/32.jpg" alt="#" title="#" /></li>
<li><img src="img/33.jpg" alt="#" title="#" /></li>
<li><img src="img/34.jpg" alt="#" title="#" /></li>
<li><img src="img/35.jpg" alt="#" title="#" /></li>
<li><img src="img/36.jpg" alt="#" title="#" /></li>
<li><img src="img/37.jpg" alt="#" title="#" /></li>
</ul>
</div>
</body>
</html>

A continuación, les damos el código del archivo CSS, que se llamará “estilo.css” y se debe ubicar en el mismo directorio que la página “index.html”. En caso de querer renombrar el archivo o colocarlo dentro de un subdirectorio, como se hace normalmente, se debe modificar la ruta del enlace que se encuentra entre <head> y </head>.

Quote
/* CAPAS CONTENEDORAS */

#izquierda {
width: 170px;
float: left;
}

.derecha {
width: 750px;
float: left;
}

/* ELEMENTOS DEL MENU LATERAL */

#menu {
padding:0;
margin:0 auto;
list-style-type:none;
width:160px;
height:312px;
}
#menu li a {
height:30px;
width:160px;
float:left;
border-bottom:2px solid #fff;
overflow: hidden;
}
#menu li a img {
border:0;
}
#menu li a:hover {
height:120px;
}

/* ELEMENTOS DEL MENU SUPERIOR */

#menu2 {
padding:0;
margin:0 auto;
list-style-type:none;
height:120px;
width:354px;
}
#menu2 li a {
width:30px;
height:120px;
float:left;
border-right:2px solid #fff;
overflow: hidden;
}
#menu2 li a img {
border:0;
}
#menu2 li a:hover {
background:#eee;
width:160px;
}

/* ELEMENTOS DE LA GALERIA DE IMAGENES */

#galeria {
padding:0;
margin:40px auto 0 auto;
list-style-type:none;
height:300px;
width:774px;
border:1px solid #888;
}
#galeria li {
width:60px;
height:300px;
float:left;
border-left:2px solid #000;
}
#galeria li img {
height:300px;
width:60px;
border:0;
}
#galeria li:hover {
background:#eee;
width:400px;
}
#galeria li:hover img {
width:400px;
}

Explicación
En primer lugar diremos que el ejemplo se encuentra dividido en tres capas flotantes, una a la izquierda, en forma de columna lateral, donde se ubica el ejemplo de menú vertical. A la derecha, dos capas contienen el menú horizontal y el ejemplo de una galería de imágenes, una arriba y la otra abajo. Las capas utilizadas utilizan un identificador (#izquierda) y una clase (.derecha) y son flotantes a la izquierda.

La capa contenedora
En los menús y la galería se emplea el mismo código con leves modificaciones. En primer lugar, debemos limitar el tamaño de la capa que contiene el menú, que tiene el identificador #menu en el archivo CSS, lo que debe ser bien calculado ya que un error en esto puede originar fallas en el funcionamiento. El ancho de esta capa debe ser el ancho de las imágenes que se utilizarán, que en este caso es de 160 pixeles.

El cálculo debe hacerse en la altura de la capa contenedora. Colocaremos siete imágenes, que en su tamaño plegado tendrán 30 pixeles mas 2 pixeles del borde blanco, es decir, un total de 32 pixeles, y en su tamaño desplegado es de 120. Como el tamaño de la capa debe ser igual al de seis imágenes plegadas y una desplegada, el cálculo que se debe hacer es (6*32) + 120, lo que da un total de 312 pixeles.

Otras propiedades utilizadas son el margen, que en este caso es 0 auto, para que se centre en la capa contenedora; en esta capa también se determina que las listas no tendrán estilo de lista, para que no aparezcan los marcadores de ítems.

Los ítems
En el caso de los menús, cada uno de los ítems de la lista contiene un enlace, por lo que para darles el formato a todos, utilizaremos #menu li a (formato del ítem que contiene un enlace dentro de la capa #menu).

Las propiedades que determinaremos son las de las imágenes contraídas, por lo que la altura será de 30 pixeles. Para que las capas se superpongan y no queden desplegadas (válido solo para los menús, ya que el caso de la galería tiene la diferencia que las imágenes contraídas están redimensionadas), es necesario que los ítems de menú sean flotantes, lo que queda indicado con la propiedad correspondiente.

Para ganar en efecto decorativo, se ha determinado que cada ítem de menú tenga un borde blanco de 2 pixeles. Luego, se determina que todo lo que sobresalga de las dimensiones de la capa quede invisible mediante la propiedad b“overflow:hidden”. De no colocarse, todas las imágenes quedarán en su tamaño original.

Imágenes con enlaces
Las imágenes con enlace tienen por defecto un borde azul de 1 pixel, que debe ser eliminado para que el mismo no se vea, utilizando la propiedad “border: 0” en “#menu li a img”, es decir, en las imágenes con enlace en un ítem de menú dentro de la capa “#menu”.

Las imágenes desplegadas
Cuando el puntero pasa o se posa sobre una de las imágenes contraídas, se activa la pseudoclase :hover, que en este caso determina que la altura de la imagen pase de los 30 pixeles a los 120 pixeles, que es la medida real de cada una de las imágenes utilizadas.

El efecto
Cuando una de las imágenes contraídas, desplaza hacia abajo a las capas que se encuentran debajo de ella, excepto la última, que solo completa el espacio disponible en la capa #menu, haciendo que se parezca a un efecto slide rápido.

El menú horizontal
El caso del menú horizontal es igual que el anterior, con la excepción que la capa base, en este caso #menu2, es más ancha que alta, al igual que las dimensiones de las imágenes contraídas, con lo que el desplazamiento forzosamente se realiza hacia la derecha. El cálculo de las dimensiones de la capa #menu2 debe realizarse con el ancho de las imágenes, en lugar de la altura como en el caso anterior. Otra diferencia, es que el borde de la capa contraída está a la izquierda.

La galería de imágenes
La galería de imágenes es igual al ejemplo del menú horizontal (puede hacerse también con desplazamiento vertical), con la excepción de que no contiene enlaces, con lo que el código cambia ligeramente.


Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
GUARAGUAO
Mensajes: 2362
Reputación: 81
Mensaje Nº 34 | 6:11 PM
Menú CSS con imágenes precargadas (CSS Sprites)

En este post les mostraré cómo crear un menú hecho sólo a base de imágenes, precargadas (sin javascript) y amigable con los buscadores. Este método se llama CSS Sprites, y lo recomiendo muchísimo a todos porque yo estoy seguro de que a más de uno le ha pasado que cuando pasan el mouse sobre un menú que es de imágenes o que tiene una imagen de fondo, se debe esperar 1 o 2 segundos a que la imagen del rollover cargue. Eso en lo personal me parece molesto porque interfiere en mi experiencia de usuario; al precargar las imágenes le ofrecemos al usuario una experiencia más placentera. Y más adelante les mostraré cómo este método también es muy útil para Aplicaciones Web cuya presentación es en html/xhtml, así que a los desarrolladores les va a interesar puesto que optimiza la carga de aplicaciones.

Los Sprites
Primero ¿qué son los Sprites? Si dan una búsqueda por Google verán que se trata de una gran imagen que contiene más imágenes pequeñas dentro. Los Sprites eran usados en los videojuegos antiguos de 2D, esos que tenían pocos colores, para tener cargados a sus personajes y mediante sus algoritmos de programación se movían dentro de esta gran imagen y daba como resultado el personaje moviéndose, corriendo, etc. Este es un ejemplo de sprites del famosísimo juego Mario Bros:

Pueden leer mas sobre la definición de sprites en Wikipedia

Entonces ¿qué tienen que ver los sprites con CSS? Bastante, pues les diré que esta antigua técnica nos ayuda a nosotros los diseñadores y/o desarrolladores a optimizar la carga de nuestras páginas web, y se los voy a demostrar con el ejemplo de crear un menú.

Preparando la imagen
Esta es la parte más importante, es lo que nos dará esa precarga de imágenes que queremos.
Volviendo al concepto de Sprites, lo que nos quiere decir es que en una imagen se tienen todas las imágenes que se usarán, para este caso, en una sola imagen tendré todos los estados del menú, el estado normal, el sobre o rollover, y el activo.

La siguiente es la imagen que usaré para mi ejemplo:

La imagen real tiene una dimensión de 702px de ancho x 108px de alto y pesa 9.21KB, la primera sección es el estado normal, la del medio es el rollover y el último es el estado activo, el que me dice en qué sección de la página estoy.

El menú en la página web tendrá solamente 36px de alto, entonces como se habrán dado cuenta si separan cada sección de la imagen, cada una es de 36px de alto, 36*3=108px

Esa es la idea, cuando ustedes empiecen a cortar su diseño, coloquen en un solo archivo todos los estados de su menú.

Hay que tomar nota del ancho para cada botón en esa imagen, yo usé las guías del photoshop y a partir de ahí medí el ancho para cada botón.

Preparando el XHTML
Entonces creamos la clásica lista para nuestro menú.

Código:

Quote
<ul class="menuholder">
<li class="menu_intro"><a href="#" title="Introduction" class="active">Introduction</a></li>
<li class="menu_book"><a href="#" title="The Book">The Book</a></li>
<li class="menu_testi"><a href="#" title="Testimonials">Testimonials</a></li>
<li class="menu_what"><a href="#" title="What You Will Get">What You Will Get</a></li>
<li class="menu_buy"><a href="#" title="Buy Now">Buy Now</a></li>
</ul>

Notar que cada link tiene su respectivo atributo title y que se ha mantenido el texto dentro del link <a>, esto es para que sea accesible y amigable con los buscadores.

Es importante que cada <li> llame a una clase distinta, y colocar una clase llamada "active" a la opción del menú que se desea mostrar como activa.

Y bueno como ven la parte del html es la más fácil no hay mucha ciencia, ahora pasaremos a la hoja de estilos.

El CSS
OK, primero asegúrense de tener un Reset en su archivo CSS. Para fines de este tip usaré el siguiente:

Código:

Quote
<span style="font-family:Courier">* {margin:0px;padding:0px;}
ul,li {list-style-type:none;}

Ahora vamos a definir ciertos parámetros para la clase "menuholder" que es el <ul> que encierra el menú.

Código:

Quote
.menuholder {background:url(images/bgmenu.gif) #dd0069;} /*opcional*/
.menuholder li {float:left;}
.menuholder a {background:url(images/menu-options.gif);display:block; height:36px; text-indent:-9000%}

En la primera línea estoy colocándole un fondo fucsia con una pequeñísima imágen de 1px de ancho por 36px de alto. Esto es para que salga de frente un fondo fucsia en mi menú rápido mientras cargan la imágen del menú. Esto es opcionanal pero la considero una buena práctica.

En la segunda línea hago que los elementos <li> dentro de .menuholder tengan float:leftb para que salgan todos en fila, en una sola línea, ya no como una lista hacia abajo.

En la tercera línea finalmente vemos que todos los links <a> dentro de .menuholder tendán de imágen de fondo menu-options.gif que es nuestra gran imagen con todos los estado. Se le define un display: block para que se le puedan aplicar el ancho y el alto a cada link, lo que sigue justamente es el alto de 36px ya que cada link tiene el mismo alto lo ponemos aquí y el text-indent moverá el texto dentro de los links bien lejos para que no se vean sobre el menú.

Ahora sí viene lo bueno, este es resto del CSS, que se encargará de posicionar la imagen de fondo en cada estado del menú:

Código:

Quote
/*ESTADO NORMAL*/
.menu_intro a {width:155px;}
.menu_book a {width:107px; background-position:-155px 0px;}
.menu_testi a {width:134px; background-position:-262px 0px;}
.menu_what a {width:176px; background-position:-396px 0px;}
.menu_buy a {width:130px; background-position:-572px 0px;}

/*ESTADO ROLLOVER*/
.menu_intro a:hover {background-position:0px -36px;}
.menu_book a:hover{background-position:-155px -36px;}
.menu_testi a:hover {background-position:-262px -36px;}
.menu_what a:hover {background-position:-396px -36px;}
.menu_buy a:hover {background-position:-572px -36px;}

/*ESTADO ACTIVO*/
.menu_intro a.active {background-position:0px -72px;}
.menu_book a.active {background-position:-155px -72px;}
.menu_testi a.active {background-position:-262px -72px;}
.menu_what a.active {background-position:-396px -72px;}
.menu_buy a.active {background-position:-572px -72px;}

¿Recuerdan que tomamos nota de los anchos? Bueno aquí es donde se usan, en la primera sección donde están los estados normales, se especifica el ancho de cada link, notar que estoy poniendo el nombre de la clase y luego la etiqueta de link <a>, porque es al link que esta dentro de la clase al que estoy aplicando todas estas definiciones. Luego juego con la posición del fondo, como ven sólo estoy moviendo las posiciones horizontales (eje X), en el primero no le especifiqué porque un fondo por defecto esta en la coordenada 0,0 así que no es necesario escribir la posición en este caso en particular.

Para el estado rollover muevo todos los backgrounds en el eje Y a -36px para que pase a la sección media de la imagen donde están todas mis imágenes de rollover, las posiciones horizontales se mantienen.

Y por ultimo el estado activo, muevo los backgrounds 36px más, es decir -72px en el eje Y para que se puedan ver los estados activos, y nuevamente mantengo los del eje X. Notar que la etiqueta <a> esta definiendo una clase "active" esto se coloca en el link <a> que se desea mostrar activo y en este caso es el primer botón del menú. ¡Y ya está!

Eso es todo, espero que hayan entendido, pueden ver el ejemplo en línea y descargar este ejemplo (notar que no hay retraso al mostrar las imágenes del menú)

  • Ver ejemplo online
  • Descargar archivos

    Tip para desarrolladores
    Este método no se limita solamente a menús en páginas web, esto ayuda bastante en la optimización de aplicaciones web también, ya que evitamos constantes conexiones al servidor cada vez que se necesite un icono, imagen, fondo, etc. Las aplicaciones web utilizan bastantes iconos, les pongo el ejemplo de Yahoo! Mail, ellos usan este método para sus iconos y fondos de los tabs, esta es una pequeñísima parte de la gran imagen que ellos usan para sus iconos, la original es de 3050px de ancho x 101px de alto, y pesa tan sólo 31kb:

    Y usan otra gran imagen para el fondo de sus tabs también.

    Como ven este método es muy útil, úsenlo sabiamente donde lo vean necesario, especialmente en imágenes estáticas que saben que van a ser llamadas una y otra vez.

    Espero que esta información les sirva para proyectos futuros.
    [/size]


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
  • GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 35 | 7:00 PM
    Cómo usar el componente Accordion de Adobe Spry

    Introducción

    Seguramente algunas vez visitamos el sitio web de Adobe, y una de las cosas que más nos llaman la atención es el efecto acordion que se usa para reducir el espacio necesario para mostrar alguna parte de nuestro sitio, y que en el caso de Adobe se usa para que en lugar de tener una tabla con 3 celdas en fila vertical, que corresponden a las secciones: Productos, Soluciones y Sectores; se pueda usar un acordion que al pasar el mouse sobre una sección, esta se expanda y al pasarlo sobre otra suceda lo mismo pero la anterior se vuelve a contraer.

    Si no sabes a que me refiero puedes ver el efecto desde la web de Adobe.

    ¿Cómo es que nos ayuda este componente?

    El componente Accordion (como se nombra en inglés) nos ayuda al momento de tener una gran cantidad de contenido que mostrar, como una lista de links recomendados o las categorías de nuestro blog o sitio, o simplemente para darle un aspecto más elegante a nuestro página web.

    Acerca de
    La versión de este componente usado en la página de Adobe es la 2007 (ó 2008 no recuerdo bien), la cual esta protegida por una licencia, por lo que sería un delito usarla sin permiso de Adobe.

    Pero al menos se encuentra disponible la versión 2006 en estado libre, la cual usaremos para este tip, esta versión es posible descargarla desde Adobe Labs, pero para que te ahorres esta descarga, les dejo los códigos necesarios para su uso. La única desventaja es que se debe dar click sobre la sección para que se expanda.

    Usar el componente
    Pues luego de todo lo anterior procedamos a crear este efecto.

    Primero que nada, al descargar el componente desde Adobe Labs tendríamos 3 archivos:

    SpryAccordion.css
    SpryAccordion.js
    SpryAccordion.html

  • El primero es la hoja de estilos que define los colores entre otras cosas de cada panel.
  • El segundo es el que realiza prácticamente todo el trabajo sucio, es un código JavaScript.
  • El tercero es solo el documento HTML en el que se da el ejemplo para visualizarlo desde el navegador.

    Antes de abrir el Dreamweaver debemos de crear una carpeta nueva dentro de cualquier lugar de nuestra PC, esta la llamaremos "Accordion"; solo para tener las cosas en un solo lugar.

    Ahora si abrimos el Dreamweaver (o incluso si no lo tienen bastará con usar el Bloc de notas) y creamos una nueva hoja de estilos en cascada (CSS)

    Y agregamos el siguiente código:

    Quote
    @charset "UTF-8";

    /* SpryAccordion.css - version 0.4 - Spry Pre-Release 1.6.1 */

    /* Copyright © 2006. Adobe Systems Incorporated. All rights reserved. */

    /* Aquí se define el estilo para el contenedor del Accordion. Como estilo
    * predeterminado, se dibujan bordes por la izquierda, derecha y abajo. El borde
    * de la parte de arriba se define por el primer panel en AccordionPanelTab, que
    * es el de mero arriba, el que nunca se mueve.
    */
    .Accordion {
    border-left: solid 1px gray;
    border-right: solid 1px black;
    border-bottom: solid 1px gray;
    overflow: hidden;
    }

    /* Aquí se define el AccordionPanel, es decir el panel que contiene todas
    * las cosas que ponemos. Aunque no tiene ningún aspecto gráfico
    * es necesario dejarlo en claro que debe de tener 0 en margin y padding.
    */
    .AccordionPanel {
    margin: 0px;
    padding: 0px;
    }

    /* Aquí se define el AccordionPanelTab, la pestaña que lleva el título
    * del panel y donde se detecta el click para abrir cualquier panel.

    .AccordionPanelTab {
    background-color: #333;
    border-top: solid 1px black;
    border-bottom: solid 1px gray;
    margin: 0px;
    padding: 2px;
    cursor: pointer;
    -moz-user-select: none;
    -khtml-user-select: none;
    font-size: 14px;
    }

    /* Aquí se define el AccordionPanelContent, donde se encuentra el contenido del panel.
    * Es importante saber que no se debe de poner ningún padding nunca al area que
    * del contenido del panel para usar las animaciones. Siempre se debe de poner 0px
    * de padding, porque si no la altura de los paneles se cambian al animarse la expansión.
    *
    * Cualquiera que estilize un acordion, debe de establecer la altura en el
    * contenedor con la clase "AccordionPanelContent"
    */
    .AccordionPanelContent {
    overflow: auto;
    margin: 0px;
    padding: 0px;
    height: 200px;
    color: #000;
    }

    /* Este es un ejemplo de como cambiar la apariencia de la pestaña de un panel abierto.
    * La clase "AccordionPanelOpen" es agregada y removida a el panel según el usuario
    * haga click sobre la pestaña del acordion.
    */
    .AccordionPanelOpen .AccordionPanelTab {
    background-color:#666;
    font-size: 14px;
    }

    /* Este es un ejemplo de como cambiar la apariencia de la pestaña del panel cuando
    * el mouse se coloca sobre ella. El nombre de clase "AccordionPanelTabHover" es
    * agregada y removida de forma programada a las pestañas del panel en mientras el mouse
    * haya abierto un panel. En este caso, yo configuré la CSS a mi gusto, y deje el mismo
    * color (#CCC) para el panel abierto al hacerle over, que a los que quedan cerrados;
    * pero si lo deseas puedes optar por cambiarlo.
    */
    .AccordionPanelTabHover {
    color: #CCC;
    }
    .AccordionPanelOpen .AccordionPanelTabHover {
    color: #CCC;
    }

    /* Este es un ejemplo de como personalizar la apariencia de todas las pestañas del panel
    /* mientras estemos enfocados en el Accordion. La clase "AccordionFocused" es agregada
    /* y removida de forma programada al Accordion al detectarse que se use o no.
    /* En esta ocasion también puse el mismo color (#333) al estar usandose o no el acordion.
    /* pero si lo deseas puedes cambiarlo.
    */
    .AccordionFocused .AccordionPanelTab {
    background-color: #333;
    }

    /* Este es un ejemplo de como puede cambiarse la apariencia de la pestaña de panel que esta
    /* abierto mientras el panel este en uso.
    * Por cuestion de gustos también deje el color (#666) igual al estar en uso el acordion y
    * al no estarlo
    */
    .AccordionFocused .AccordionPanelOpen .AccordionPanelTab {
    background-color: #666;
    }
    [/css]

    Iba a explicar cada función de las clases que se especifican, pero me di cuenta de que eran muchas y resultaría muy confuso buscarlas entre el código, así que la explicación la puse junto al código.

    Nota: Es importante que leas los comentarios añadidos al código para que veas algunas reglas básicas en el diseño del componente, y su correcta función.

    Con respecto a las siguientes clases:


      .Accordion
      .AccordionPanel
      .AccordionPanelTab
      .AccordionPanelContent

    No es importante su nombre de clase para que el efecto funcione de forma correcta, puedes usar cualquier otro nombre de clase para darle estilo.

    Y en todas las partes donde menciono que son solo ejemplos de personalizar el componente Accordion, son solo si queremos definir o personalizar mas el componente. Pero no es necesario que se haga uso de ellos.

    En la definición de la clase .AccordionPanelTab se usan las propiedades "-moz-user-select" y "-khtml-user-select" para evitar que el usuario pueda seleccionar el texto en AccordionPanelTab (las pestañas del acordion). Esas propiedades de los navegadores solo funcionan en navegadores basados en Mozilla (como Firefox) y también en los que se basan en KHTML (como Safari), pero no pasan la validación de W3C. Si quieres usarlo y que sea válido el código, y no te importa si se puede seleccionar el texto que esta en las pestañas del acordion puedes remover esas 2 líneas, y no se dañará el componente ni sus funciones.

    Dejando en claro todo lo anterior, y con nuestro código bien definido y/o corregido procedemos a guardar nuestro documento con el nombre: SpryAccordion y su respectiva extensión (.css)

    Ahora procedamos al código JavaScript (JS), el cual posee una declaración sobre derechos de autor etcétera, etcétera, etcétera... en los comentarios. Por lo que les aviso que na vayan a usarlo sin cumplir sus condiciones, las cuales removí para el tip, pero que si desean modificarlo considero que deberán leer el código original desde aquí.

    Con respecto al código JavaScript les tengo una mala noticia:

    ...

    Por desgracia no se JS

    Y me había propuesto darle un breve analisis al código a ver si entendía algo, pero con solo ver la extensión del código me dio miedo

    Así que aquí se los dejo tal cual es (omitiendo lo de la declaración de derechos de autor).

    Creamos un nuevo documento de JavaScript y pegamos el siguiente código:

    Quote
    // SpryAccordion.js - version 0.15 - Spry Pre-Release 1.6.1
    //
    // Copyright © 2006. Adobe Systems Incorporated.
    // All rights reserved.

    var Spry;
    if (!Spry) Spry = {};
    if (!Spry.Widget) Spry.Widget = {};

    Spry.Widget.Accordion = function(element, opts)
    {
    this.element = this.getElement(element);
    this.defaultPanel = 0;
    this.hoverClass = "AccordionPanelTabHover";
    this.openClass = "AccordionPanelOpen";
    this.closedClass = "AccordionPanelClosed";
    this.focusedClass = "AccordionFocused";
    this.enableAnimation = true;
    this.enableKeyboardNavigation = true;
    this.currentPanel = null;
    this.animator = null;
    this.hasFocus = null;

    this.previousPanelKeyCode = Spry.Widget.Accordion.KEY_UP;
    this.nextPanelKeyCode = Spry.Widget.Accordion.KEY_DOWN;

    this.useFixedPanelHeights = true;
    this.fixedPanelHeight = 0;

    Spry.Widget.Accordion.setOptions(this, opts, true);

    this.attachBehaviors();
    };

    Spry.Widget.Accordion.prototype.getElement = function(ele)
    {
    if (ele && typeof ele == "string")
    return document.getElementById(ele);
    return ele;
    };

    Spry.Widget.Accordion.prototype.addClassName = function(ele, className)
    {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
    return;
    ele.className += (ele.className ? " " : "") + className;
    };

    Spry.Widget.Accordion.prototype.removeClassName = function(ele, className)
    {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
    return;
    ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
    };

    Spry.Widget.Accordion.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
    {
    if (!optionsObj)
    return;
    for (var optionName in optionsObj)
    {
    if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
    continue;
    obj[optionName] = optionsObj[optionName];
    }
    };

    Spry.Widget.Accordion.prototype.onPanelTabMouseOver = function(e, panel)
    {
    if (panel)
    this.addClassName(this.getPanelTab(panel), this.hoverClass);
    return false;
    };

    Spry.Widget.Accordion.prototype.onPanelTabMouseOut = function(e, panel)
    {
    if (panel)
    this.removeClassName(this.getPanelTab(panel), this.hoverClass);
    return false;
    };

    Spry.Widget.Accordion.prototype.openPanel = function(elementOrIndex)
    {
    var panelA = this.currentPanel;
    var panelB;

    if (typeof elementOrIndex == "number")
    panelB = this.getPanels()[elementOrIndex];
    else
    panelB = this.getElement(elementOrIndex);

    if (!panelB || panelA == panelB)
    return null;

    var contentA = panelA ? this.getPanelContent(panelA) : null;
    var contentB = this.getPanelContent(panelB);

    if (!contentB)
    return null;

    if (this.useFixedPanelHeights && !this.fixedPanelHeight)
    this.fixedPanelHeight = (contentA.offsetHeight) ? contentA.offsetHeight : contentA.scrollHeight;

    if (this.enableAnimation)
    {
    if (this.animator)
    this.animator.stop();
    this.animator = new Spry.Widget.Accordion.PanelAnimator(this, panelB, { duration: this.duration, fps: this.fps, transition: this.transition });
    this.animator.start();
    }
    else
    {
    if(contentA)
    {
    contentA.style.display = "none";
    contentA.style.height = "0px";
    }
    contentB.style.display = "block";
    contentB.style.height = this.useFixedPanelHeights ? this.fixedPanelHeight + "px" : "auto";
    }

    if(panelA)
    {
    this.removeClassName(panelA, this.openClass);
    this.addClassName(panelA, this.closedClass);
    }

    this.removeClassName(panelB, this.closedClass);
    this.addClassName(panelB, this.openClass);

    this.currentPanel = panelB;

    return panelB;
    };

    Spry.Widget.Accordion.prototype.closePanel = function()
    {
    // The accordion can only ever have one panel open at any
    // give time, so this method only closes the current panel.
    // If the accordion is in fixed panel heights mode, this
    // method does nothing.

    if (!this.useFixedPanelHeights && this.currentPanel)
    {
    var panel = this.currentPanel;
    var content = this.getPanelContent(panel);
    if (content)
    {
    if (this.enableAnimation)
    {
    if (this.animator)
    this.animator.stop();
    this.animator = new Spry.Widget.Accordion.PanelAnimator(this, null, { duration: this.duration, fps: this.fps, transition: this.transition });
    this.animator.start();
    }
    else
    {
    content.style.display = "none";
    content.style.height = "0px";
    }
    }
    this.removeClassName(panel, this.openClass);
    this.addClassName(panel, this.closedClass);
    this.currentPanel = null;
    }
    };

    Spry.Widget.Accordion.prototype.openNextPanel = function()
    {
    return this.openPanel(this.getCurrentPanelIndex() + 1);
    };

    Spry.Widget.Accordion.prototype.openPreviousPanel = function()
    {
    return this.openPanel(this.getCurrentPanelIndex() - 1);
    };

    Spry.Widget.Accordion.prototype.openFirstPanel = function()
    {
    return this.openPanel(0);
    };

    Spry.Widget.Accordion.prototype.openLastPanel = function()
    {
    var panels = this.getPanels();
    return this.openPanel(panels[panels.length - 1]);
    };

    Spry.Widget.Accordion.prototype.onPanelTabClick = function(e, panel)
    {
    if (panel != this.currentPanel)
    this.openPanel(panel);
    else
    this.closePanel();

    if (this.enableKeyboardNavigation)
    this.focus();

    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;

    return false;
    };

    Spry.Widget.Accordion.prototype.onFocus = function(e)
    {
    this.hasFocus = true;
    this.addClassName(this.element, this.focusedClass);
    return false;
    };

    Spry.Widget.Accordion.prototype.onBlur = function(e)
    {
    this.hasFocus = false;
    this.removeClassName(this.element, this.focusedClass);
    return false;
    };

    Spry.Widget.Accordion.KEY_UP = 38;
    Spry.Widget.Accordion.KEY_DOWN = 40;

    Spry.Widget.Accordion.prototype.onKeyDown = function(e)
    {
    var key = e.keyCode;
    if (!this.hasFocus || (key != this.previousPanelKeyCode && key != this.nextPanelKeyCode))
    return true;

    var panels = this.getPanels();
    if (!panels || panels.length < 1)
    return false;
    var currentPanel = this.currentPanel ? this.currentPanel : panels[0];
    var nextPanel = (key == this.nextPanelKeyCode) ? currentPanel.nextSibling : currentPanel.previousSibling;

    while (nextPanel)
    {
    if (nextPanel.nodeType == 1 /* Node.ELEMENT_NODE */)
    break;
    nextPanel = (key == this.nextPanelKeyCode) ? nextPanel.nextSibling : nextPanel.previousSibling;
    }

    if (nextPanel && currentPanel != nextPanel)
    this.openPanel(nextPanel);

    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;

    return false;
    };

    Spry.Widget.Accordion.prototype.attachPanelHandlers = function(panel)
    {
    if (!panel)
    return;

    var tab = this.getPanelTab(panel);

    if (tab)
    {
    var self = this;
    Spry.Widget.Accordion.addEventListener(tab, "click", function(e) { return self.onPanelTabClick(e, panel); }, false);
    Spry.Widget.Accordion.addEventListener(tab, "mouseover", function(e) { return self.onPanelTabMouseOver(e, panel); }, false);
    Spry.Widget.Accordion.addEventListener(tab, "mouseout", function(e) { return self.onPanelTabMouseOut(e, panel); }, false);
    }
    };

    Spry.Widget.Accordion.addEventListener = function(element, eventType, handler, capture)
    {
    try
    {
    if (element.addEventListener)
    element.addEventListener(eventType, handler, capture);
    else if (element.attachEvent)
    element.attachEvent("on" + eventType, handler);
    }
    catch (e) {}
    };

    Spry.Widget.Accordion.prototype.initPanel = function(panel, isDefault)
    {
    var content = this.getPanelContent(panel);
    if (isDefault)
    {
    this.currentPanel = panel;
    this.removeClassName(panel, this.closedClass);
    this.addClassName(panel, this.openClass);

    // Attempt to set up the height of the default panel. We don't want to
    // do any dynamic panel height calculations here because our accordion
    // or one of its parent containers may be display:none.

    if (content)
    {
    if (this.useFixedPanelHeights)
    {
    // We are in fixed panel height mode and the user passed in
    // a panel height for us to use.

    if (this.fixedPanelHeight)
    content.style.height = this.fixedPanelHeight + "px";
    }
    else
    {
    // We are in variable panel height mode, but since we can't
    // calculate the panel height here, we just set the height to
    // auto so that it expands to show all of its content.

    content.style.height = "auto";
    }
    }
    }
    else
    {
    this.removeClassName(panel, this.openClass);
    this.addClassName(panel, this.closedClass);

    if (content)
    {
    content.style.height = "0px";
    content.style.display = "none";
    }
    }

    this.attachPanelHandlers(panel);
    };

    Spry.Widget.Accordion.prototype.attachBehaviors = function()
    {
    var panels = this.getPanels();
    for (var i = 0; i < panels.length; i++)
    this.initPanel(panels[i], i == this.defaultPanel);

    // Advanced keyboard navigation requires the tabindex attribute
    // on the top-level element.

    this.enableKeyboardNavigation = (this.enableKeyboardNavigation && this.element.attributes.getNamedItem("tabindex"));
    if (this.enableKeyboardNavigation)
    {
    var self = this;
    Spry.Widget.Accordion.addEventListener(this.element, "focus", function(e) { return self.onFocus(e); }, false);
    Spry.Widget.Accordion.addEventListener(this.element, "blur", function(e) { return self.onBlur(e); }, false);
    Spry.Widget.Accordion.addEventListener(this.element, "keydown", function(e) { return self.onKeyDown(e); }, false);
    }
    };

    Spry.Widget.Accordion.prototype.getPanels = function()
    {
    return this.getElementChildren(this.element);
    };

    Spry.Widget.Accordion.prototype.getCurrentPanel = function()
    {
    return this.currentPanel;
    };

    Spry.Widget.Accordion.prototype.getPanelIndex = function(panel)
    {
    var panels = this.getPanels();
    for( var i = 0 ; i < panels.length; i++ )
    {
    if( panel == panels[i] )
    return i;
    }
    return -1;
    };

    Spry.Widget.Accordion.prototype.getCurrentPanelIndex = function()
    {
    return this.getPanelIndex(this.currentPanel);
    };

    Spry.Widget.Accordion.prototype.getPanelTab = function(panel)
    {
    if (!panel)
    return null;
    return this.getElementChildren(panel)[0];
    };

    Spry.Widget.Accordion.prototype.getPanelContent = function(panel)
    {
    if (!panel)
    return null;
    return this.getElementChildren(panel)[1];
    };

    Spry.Widget.Accordion.prototype.getElementChildren = function(element)
    {
    var children = [];
    var child = element.firstChild;
    while (child)
    {
    if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
    children.push(child);
    child = child.nextSibling;
    }
    return children;
    };

    Spry.Widget.Accordion.prototype.focus = function()
    {
    if (this.element && this.element.focus)
    this.element.focus();
    };

    Spry.Widget.Accordion.prototype.blur = function()
    {
    if (this.element && this.element.blur)
    this.element.blur();
    };

    /////////////////////////////////////////////////////

    Spry.Widget.Accordion.PanelAnimator = function(accordion, panel, opts)
    {
    this.timer = null;
    this.interval = 0;

    this.fps = 60;
    this.duration = 500;
    this.startTime = 0;

    this.transition = Spry.Widget.Accordion.PanelAnimator.defaultTransition;

    this.onComplete = null;

    this.panel = panel;
    this.panelToOpen = accordion.getElement(panel);
    this.panelData = [];
    this.useFixedPanelHeights = accordion.useFixedPanelHeights;

    Spry.Widget.Accordion.setOptions(this, opts, true);

    this.interval = Math.floor(1000 / this.fps);

    // Set up the array of panels we want to animate.

    var panels = accordion.getPanels();
    for (var i = 0; i < panels.length; i++)
    {
    var p = panels[i];
    var c = accordion.getPanelContent(p);
    if ©
    {
    var h = c.offsetHeight;
    if (h == undefined)
    h = 0;

    if (p == panel && h == 0)
    c.style.display = "block";

    if (p == panel || h > 0)
    {
    var obj = new Object;
    obj.panel = p;
    obj.content = c;
    obj.fromHeight = h;
    obj.toHeight = (p == panel) ? (accordion.useFixedPanelHeights ? accordion.fixedPanelHeight : c.scrollHeight) : 0;
    obj.distance = obj.toHeight - obj.fromHeight;
    obj.overflow = c.style.overflow;
    this.panelData.push(obj);

    c.style.overflow = "hidden";
    c.style.height = h + "px";
    }
    }
    }
    };

    Spry.Widget.Accordion.PanelAnimator.defaultTransition = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); };

    Spry.Widget.Accordion.PanelAnimator.prototype.start = function()
    {
    var self = this;
    this.startTime = (new Date).getTime();
    this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
    };

    Spry.Widget.Accordion.PanelAnimator.prototype.stop = function()
    {
    if (this.timer)
    {
    clearTimeout(this.timer);

    // If we're killing the timer, restore the overflow
    // properties on the panels we were animating!

    for (i = 0; i < this.panelData.length; i++)
    {
    obj = this.panelData[i];
    obj.content.style.overflow = obj.overflow;
    }
    }

    this.timer = null;
    };

    Spry.Widget.Accordion.PanelAnimator.prototype.stepAnimation = function()
    {
    var curTime = (new Date).getTime();
    var elapsedTime = curTime - this.startTime;

    var i, obj;

    if (elapsedTime >= this.duration)
    {
    for (i = 0; i < this.panelData.length; i++)
    {
    obj = this.panelData[i];
    if (obj.panel != this.panel)
    {
    obj.content.style.display = "none";
    obj.content.style.height = "0px";
    }
    obj.content.style.overflow = obj.overflow;
    obj.content.style.height = (this.useFixedPanelHeights || obj.toHeight == 0) ? obj.toHeight + "px" : "auto";
    }
    if (this.onComplete)
    this.onComplete();
    return;
    }

    for (i = 0; i < this.panelData.length; i++)
    {
    obj = this.panelData[i];
    var ht = this.transition(elapsedTime, obj.fromHeight, obj.distance, this.duration);
    obj.content.style.height = ((ht < 0) ? 0 : ht) + "px";
    }

    var self = this;
    this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
    };

    Si alguien aquí sabe JS y se atreviese a explicar el código anterior, creo que ya tiene una buena razón para escribir un tip sobre esto.
    Lo guardamos como SpryAccordion con la extensión de un código JavaScript (.js)

    Pues ahora pasemos al documento HTML.

    Creamos un nuevo documento HTML, y pegamos el siguiente código:

    Quote





    Spry Accordion
















    Panel 1




    Aquí va el contenido del panel 1







    Panel 2


    Aquí va el contenido del panel 2



    Panel 3


    Aquí va el contenido del panel 3



    Panel 4


    Aquí va el contenido del panel 4







    Guardamos el archivo como SpryAccordion con la extensión (.html).

    El código también lo explico en él.

    El resultado final lo puedes visualizar desde aquí

    Para más información puedes entrar a Adobe Labs > Accordion Widget

  • Descargar archivos del tip (RAR)
  • Descargar archivos del tip (ZIP)
    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
  • GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 36 | 6:47 PM
    Cómo crear un menú desplegable con Jquery

    Hay que tomar en cuenta algunas cosas como por ejemplo que es el DOM (Modelo de Objetos del Documento). El DOM se conforma de todas tus etiquetas desde <html> hasta </html>. Todo lo que este dentro de estas etiquetas representa el DOM y Jquery se ejecuta muchas veces hasta que el DOM esta completamente cargado, esto lo podemos ver porque encontraremos en la estructura algo como esto:

    Quote
    $(document).ready(function() {
    //aqui escribes tu codigo
    }
    O podras ver tambien…
    $(function(){
    //aqui escribes tu codigo
    });

    Y se preguntaran bien y de donde veo mas ejemplos o donde bajo esta librería pues desde este link www.jquery.com

    Jquery ha sacado librerías para poder personalizar los aburridos componentes como los List, Radio, Checkbox, entre otras cosas.

    Supongamos que queremos hacer rollover de un div y que debajo de el aparezca otro.

    Abriremos un archivo ya sea HTML o PHP como ustedes gusten, luego dentro de <body> vamos a crear 3 DIVS con su respectivo ID y el CSS, a estos dos DIVS vamos a ponerles un color de fondo diferente.

    Código:

    Quote
    div#uno a {
    background-color:#993300;
    width:20px;
    height:20px;
    display:block;
    }
    div#Cont_serv {
    width:20px;
    height:20px;
    display:none;
    // NOTA VEASE QUE ESTE ID CONTIENE UN DISPLAY:NONE ESTO QUIERE DECIR QUE ES EL OBJETO AFECTAR Y LO
    // NECESITAMOS EN PRINCIPIO OCULTO y dentro de el tendremos el DIV con ID dos.
    }
    div#dos a {
    background-color:#009999;
    width:20px;
    height:20px;
    display:block;
    }
    <body>
    <div id=”contMenu” style=”width:350px; height:20px;”>
    <div id=”uno”><a href=”javascript:void(0);”></a></div></div>
    <div id=”Cont_serv”>
    <div id=”dos”><a href=”javascript:void(0);”></a></div>
    </div>
    </body>

    Debemos importar nuestra librería Jquery antes de la etiqueta de cierre del </head>]:

    Código:

    Quote
    <script lenguaje=”javascript” type=”text/javascript” src=”js/jquery.js”></script>

    Ya teniendo agregada la librería pasaremos a construir la función del Jquery para que esta sea Ejecutada cuando nuestro Navegador haya terminado de leer o cargar el DOM. Cabe mencionar que esta función va dentro de las etiquetas <script></script> ya que siguen siendo códigos de Javascript.

    Código:

    Quote
    <script language=”javascript” type=”text/javascript”>
    $(function(){
    //aqui escribes tu codigo
    });
    </script>

    Ahora dentro de nuestra funcion vamos a poner lo siguiente:

    Código:

    Quote
    <script language=”javascript” type=”text/javascript”>
    $(function(){
    $(’#uno a’).mouseover(function () {
    $(”#Cont_serv”).fadeIn(”slow”);
    })
    });
    </script>

    Te preguntarás que es eso que esta declarado en la función, es la sentencia en Jquery para poder aparecer el otro div.

    La primera parte de esta sentencia es $(’#uno a’), bien aquí es donde vamos a definir a que DIV (o mejor llamado OBJETO ) le vamos a dar la instrucción de que aparezca el otro DIV oculto, es importante poner siempre el ID del objeto entre comillas simples o dobles da igual pero también debe tener el símbolo de #.

    La segunda parte de esta sentencia se te hará conocida .mouseover, aquí le estamos indicando que cuando el mouse pase por encima del DIV $(’#uno a’). se va ejecutar lo que seria la función de

    Código:

    Quote
    .mouseover (function (){
    $(”#Cont_serv”).fadeIn(”slow”);
    })

    Como podrán observar dentro de los paréntesis del .mouseover(), hay una function que la que hará que el otro DIV aparezca tengan mucho cuidado con los signos de cierre porque luego se les escapa una llave o un paréntesis y no se ejecutara correctamente el código, bien como podrán ver dentro de la función nos encontramos de nuevo con $(”#Cont_serv”), pues aquí le decimos a que div vamos aparecer y el .fadeIn(”slow”), es el modo en que aparecerá el otro objeto.

    Ya lo hicimos aparecer ahora queremos que desaparezca al salir del objeto que lo manda aparecer bien solo agregamos la siguientes linea

    Código:

    Quote
    .mouseout(function () {$(”#Cont_serv”).fadeOut(”slow”); });

    OJO si no saben donde pondrán este código sera después del ultimo paréntesis de cierre de .onmouse().mouseout() es por eso que les comento que hay que tener cuidado el ejercicio quedaría así:

    Código:

    Quote
    $(function(){
    $(’#uno a’).mouseover(function () {
    $(”#Cont_serv”).fadeIn(”slow”);
    }).mouseout(function () {
    $(”#Cont_serv”).fadeOut(”slow”);
    });

    Ahora continuamos con la Segunda parte, la cual consiste en que el DIV de que aparece al poner cursor sobre de el este no desaparezca.

    Para ello necesitamos analizar la situación, necesitamos detener o cancelar la acción del .mouseout, asi que pues una forma de poder hacer esto es usar un intervalo y de una variable boolean.

    Fuera de la función que se ejecuta al terminar de cargar el DOM, vamos a declarar dos variables:

    Código:

    Quote
    var myInterval;
    var VAL = false;

    Acto seguido en nuestra función de .mouseover vamos a sustituir el:

    Código:

    Quote
    $(”#Cont_serv”).fadeOut(”slow”)

    ahora vamos a poner:

    Código:

    Quote
    VAL = true;
    activeInterval();

    Aquí le vamos a decir que al momento de sacar el mouse de nuestro DIV vamos a cambiar el valor de la Variable VAL a TRUE y vamos a llamar a una FUNCION llamada activeInterval, esta función se encuentra fuera de la función Jquery Seria así:

    Código:

    Quote
    function activeInterval(){
    if(VAL==true){
    myInterval = setInterval(remover,100);
    }
    }

    Como podrán apreciar validamos si VAL es igual a true, entonces ejecutamos el setInterval, (para los que no conozcan el setInterval es una función de ciclo cada determinado tiempo ), el setInterval está asignado a nuestra variable myInterval y el setInterval consta de dos parámetros. El primero es donde tenemos la palabra remover que esta es una función y el numero 100 que es el tiempo en milisegundos que tarda en ejecutarse el setInterval.

    Así que cuando hagamos mouseout cambiamos el valor de VAL y ejecutamos activeInterval. Ahora vamos a detener el intervalo porque necesitamos hacerlo cada 100 milisegundos. El intervalo se estará ejecutando bien, dentro de nuestra función de Jquery vamos agregarle al DIV que estamos haciendo que aparezca los métodos de mouseover y mouseout, de la siguiente manera:

    Código:

    Quote
    $(”#Cont_serv”).mouseover(function () {
    clearInterval(myInterval);
    }).mouseout(function () {
    VAL = true;
    activeInterval();
    });

    Al hacer mouseover cancelamos el intervalo con clearInterval. Llamamos a la variable que contiene el setInterval y que al mouseout de este objeto volvemos a llamar la función que contiene el intervalo. Nos hace falta una función por explicar.

    La función remover el código que le extrajimos originalmente a la instrucción mouseout:

    Código:

    Quote
    function remover(){
    clearInterval(myInterval);
    $(”#Cont_serv”).fadeOut(”slow”);
    }

    Al llamar la función, lo primero que hace es cancelar el intervalo y luego hacemos el fadeOut del objeto. Así fácil y sencillo. Cabe mencionar que esta estructura puede servir para hacer lo mismo con AS2 y AS3 obviamente con sus respectivas sentencias de cada lenguaje.

    Aquí puedes ver un ejemplo.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 37 | 2:22 PM
    Elegante Menú animado en CSS y JQuery

    En este tutorial vamos a crear un menú en css animado para tu sitio web.

    Paso 1
    En este paso que es sencillo vamos a crear nuestra lista de menú en nuestro documento HTML que debe ser algo así como el código que mostramos, lógicamente con las opciones del menú que tu desees.

    Quote
    <ul id="topnav">
    <li><a href="#">Inicio</a></li>
    <li><a href="#">Servicios</a></li>
    <li><a href="#">Portafolio</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">Contactenos</a></li>
    </ul>

    Paso 2
    Este es nuestro código CSS para darle estilo a nuestro menú. Este código va ANTES del código </head>

    Quote
    <style type="text/css">

    <style type="text/css">
    html { background: #cccccc; }
    body {
    margin: 0; padding: 0;
    font: 10px normal Verdana, Arial, Helvetica, sans-serif;
    background: #cccccc;
    }

    h1 small{
    font: 0.2em normal Verdana, Arial, Helvetica, sans-serif;
    text-transform:uppercase;
    letter-spacing: 1.4em;
    display: block;
    color: #ccc;
    }
    .container {
    width: 520px;
    height: 330px;
    position: absolute;
    top: 50%; left: 50%;
    margin: -165px 0 0 -210px;
    overflow: hidden;
    }
    img {border: none;}
    ul#topnav {
    margin: 10px 0 20px;
    padding: 0;
    list-style: none;
    font-size: 1.1em;
    clear: both;
    float: left;
    width: 520px;
    }
    ul#topnav li{
    margin: 0;
    padding: 0;
    overflow: hidden;
    float: left;
    height:40px;
    }
    ul#topnav a, ul#topnav span {
    padding: 10px 20px;
    float: left;
    text-decoration: none;
    color: #fff;
    text-transform: uppercase;
    clear: both;
    height: 20px;
    line-height: 20px;
    background: #1d1d1d;
    }
    ul#topnav a { color: #555;
    background: url(a_bg.gif) repeat-x left bottom; }
    ul#topnav span {
    background: url(a_bg.gif) repeat-x left top;
    }

    </style>

    Paso 3
    Descarga ahora el archivo JS que necesitamos desde aquí y colocaremos el siguiente código antes de la etiqueta </head>

    Quote
    <script type="text/javascript" src="js/jquery.min.js"></script>

    Paso 4
    Ahora agregamos este código debajo del código anterior

    Quote
    <script type="text/javascript">

    $(document).ready(function() {

    $("#topnav li").prepend("<span></span>"); //Throws an empty span tag right before the a tag

    $("#topnav li").each(function() { //For each list item...
    var linkText = $(this).find("a").html(); //Find the text inside of the a tag
    $(this).find("span").show().html(linkText); //Add the text in the span tag
    });

    $("#topnav li").hover(function() { //On hover...
    $(this).find("span").stop().animate({
    marginTop: "-40" //Find the span tag and move it up 40 pixels
    }, 250);
    } , function() { //On hover out...
    $(this).find("span").stop().animate({
    marginTop: "0" //Move the span back to its original state (0px)
    }, 250);
    });

    });
    </script>

    Paso 5
    En el zip de nuestro ejemplo adjuntamos un archivo llamado “a_bg.gif” que puedes editar y cambiar el color en photoshop.

    Eso es todo! con esto ya tenemos nuestro menú animado.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 38 | 4:34 PM
    Menú desplegable en Dreamweaver

    PASO 1
    Crear un documento nuevo HTML.

    PASO 2
    Con el comando Ctrl + S guardamos nuestro documento con el nombre de menu desplegable.html

    PASO 3
    Vamos a la ventana Insert – Layout – Spay Menu Bar

    PASO 4
    Nos aparece la ventana Spry Menu Bar y escogemos la opción que se ajuste a nuestras necesidades en este caso escogeremos un menú horizontal.

    PASO 5
    Nos aparece como se muestra en la imagen, un menú con 4 Items para poder modificar a nuestro gusto.

    PASO 6
    En la ventana Properties cambiamos los nombres de los menús principales y secundarios, agregamos links a nuestros botones y agregamos más menús.

    PASO 7
    Ya tenemos nuestro menú terminado solo para colocarle un diseño bonito.

    PASO 8
    Si nos damos cuenta en la parte derecha en la ventana CSS Styles vemos que nuestro menú tiene aplicado un css entonces ahí podemos editar colores, tipo de letra y agregare todas las modificaciones necesarias para obtener un menú machismo mejor.

    PASO 9
    Final

    Descarga el editable de Menu desplegable en Dreamweaver


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 39 | 7:00 PM
    Menú con efecto caída creado con jQuery

    Vamos a crear un menú formado por barras verticales que estarán formados por una imagen que bajará desde arriba cuando se pase el puntero del ratón por su correspondiente barra. Además cada barra vertical tendrá varias opciones que subirán desde abajo al pasar el ratón por su barra correspondiente.

    Cuando pulsemos en una de estas opciones, el resto de barras verticales desaparecerán, y la barra pulsada se situará a la izquierda, y a su derecha tendremos una capa con información de la opción pulsada.

    También tendremos un botón para volver el menú principal.

    Empezaremos por crear el menú vertical con código HTML.

    Quote
    <div id="cc_menu" class="cc_menu">
    <div class="cc_item" style="z-index:5;">
    <img src="images/1.jpg" alt="image" />
    <span class="cc_title">Collection</span>
    <div class="cc_submenu">
    <ul>
    <li class="cc_content_1">Winter 2010</li>
    <li class="cc_content_2">Spring 2011</li>
    </ul>
    </div>
    </div>
    <div class="cc_item" style="z-index:4;">
    <img src="images/2.jpg" alt="image" />
    <span class="cc_title">Stores</span>
    <div class="cc_submenu">
    <ul>
    <li class="cc_content_3">Milano</li>
    <li class="cc_content_4">Paris</li>
    </ul>
    </div>
    </div>
    ...
    <div id="cc_content" class="cc_content">
    <span id="cc_back" class="cc_back"><< Go back</span>
    <div class="cc_content_1">
    <h1>Winter 2010</h1>
    <p>Some content</p>
    </div>
    <div class="cc_content_2">
    <h1>Spring 2011</h1>
    <p>Some content</p>
    </div>
    ...
    </div>
    </div>

    Al primer elemento del menú, le pondremos la propiedad de estilos z-index con un valor de 5, cuyo valor iremos decrementando en las siguientes opciones del menú. Con esto conseguimos que el último elemento esté en la capa más baja. Hacemos esto para crear el efecto de colapso de cartas.

    Cada elemento del submenú compartirá la clase con su respectivo contenedor div. De esta forma, nosotros podremos hacer que el contenedor aparezca a la derecha cuando se pulse una opción del submenú.

    A continuación veremos los estilos.

    El div principal, .cc_menu, que rodeará al resto de elementos del menú tendrá el siguiente estilo.

    Quote
    .cc_menu{
    width:700px; /*140px * 5*/
    height:600px;
    position:relative;
    font-size:14px;
    text-transform:uppercase;
    color:#fff;
    }

    El ancho del contenedor es la suma de todos los anchos de las distintas opciones que tiene el menú. Si a cada una le damos el valor de 140 px, habrá que multiplicar eso por el número de opciones.

    Los estilos de cada elemento de la navegación es el siguiente:

    Quote
    .cc_item{
    text-align:center;
    width:140px;
    height:600px;
    float:left;
    border-bottom:1px solid #000;
    background:#444 url(../images/bg.png) repeat top left;
    position:relative;
    -moz-box-shadow:3px -3px 10px #000;
    -webkit-box-shadow:3px -3px 10px #000;
    box-shadow:3px -3px 10px #000;
    }

    A cada elemento le asignamos un box shadow para que la capa llegue a ser visible. En IE esto no funciona, por lo que habría que ponerle alguna imagen que hiciera el mismo efecto.

    El título de cada elemento del menú tendrá un fondo oscuro con una delgada sombra alrededor.

    Quote
    span.cc_title{
    color:#fff;
    font-size:16px;
    top:200px;
    left:5px;
    position:absolute;
    padding:3px 0px;
    background:#111;
    width:130px;
    display:block;
    z-index:11;
    -moz-box-shadow:1px 1px 4px #000;
    -webkit-box-shadow:1px 1px 4px #000;
    box-shadow:1px 1px 4px #000;
    }

    El submenú de cada elemento tendrá los siguientes estilos:

    Quote
    .cc_submenu ul{
    list-style:none;
    width:140px;
    margin:0;
    padding:0;
    height:0px; /*increase to 200px to slide up*/
    overflow:hidden;
    text-align:left;
    background:#000;
    position:absolute;
    left:0px;
    bottom:0px;
    opacity:0.7;
    z-index:13;
    }

    A la propiedad bottom del elemento y a su altura le asignamos el valor 0 para que esté oculto, para luego incrementar su altura en 200 pixels y crear así el efecto de aparición desde abajo.

    La lista de elementos del submenú tendrá los siguientes estilos:

    Quote
    .cc_submenu ul li{
    color:#ddd;
    cursor:pointer;
    padding:10px;
    }

    La imagen que sale desde la parte de arriba, tendrá un valor negativo en su propiedad top, de esta forma estará oculta. Luego mediante código javascript, a la propiedad top le asignaremos un valor de 0 para crear el efecto de aparecer desde arriba. Los estilos completos son los siguientes:

    Quote
    .cc_item img{
    position:absolute;
    width:140px;
    height:600px;
    top:-600px;
    left:0px;
    }

    El contenedor que rodea a todos los elementos también le damos un valor left negativo para que se muestre oculto y luego hacerlo visible mediante javascript. Los estilos para esto son los siguientes.

    Quote
    .cc_content{
    width:600px;
    height:600px;
    border-bottom:1px solid #000;
    position:absolute;
    left:-700px;
    background:#444 url(../images/bg.png) repeat top left;
    overflow:hidden;
    -moz-box-shadow:4px 0 7px #000;
    -webkit-box-shadow:4px 0 7px #000;
    box-shadow:4px 0 7px #000;
    }

    El contenido de lo divs tendrán los siguientes estilos:

    Quote
    .cc_content div{
    display:none;
    margin:20px;
    }

    A cada párrafo le asignaremos los siguientes estilos:

    Quote
    .cc_content p{
    background:#000;
    padding:20px;
    opacity:0.7;
    }

    Por último vamos a ver los estilos del botón de vuelta al menú.

    Quote
    span.cc_back{
    position:absolute;
    bottom:10px;
    right:10px;
    cursor:pointer;
    color:#ddd;
    }

    Después de ver los estilos, vamos a ver como darle animación utilizando la librería jQuery.

    Vamos a tener varias funciones que gestionarán el funcionamiento de nuestra navegación. Cada vez que nos situemos en un elemento de menú, queremos que la imagen se deslice desde la parte superior y el submenú se deslice desde la parte inferior. Y por supuesto, cuando salimos de una opción queremos el efecto contrario. Las funciones “m_enter” y “m_leave” se encargarán de ese funcionamiento.

    La función “fold” hará que el menú se colapse cada vez que un elemento del menú es pulsado. La posición inicial es recuperada por la función “unfold”.

    Las dos funciones “showContent” y “hideContent”, serán las encargadas de hacer que aparezcan o desaparezcan el contenido de los respectivos contenedores.

    En nuestro código jQuery tendremos definidas algunas funciones:

    Quote
    //all the menu items
    var $items = $('#cc_menu .cc_item');
    //number of menu items
    var cnt_items = $items.length;
    //if menu is expanded then folded is true
    var folded = false;
    //timeout to trigger the mouseenter event on the menu items
    var menu_time;

    Ahora vamos a definir lo que sucederá cuando se lancen los eventos mouseenter y mouseleave para cada elemento. También definiremos las acciones cuando se hace clic en el elemento.

    Quote
    $items.unbind('mouseenter')
    .bind('mouseenter',m_enter)
    .unbind('mouseleave')
    .bind('mouseleave',m_leave)
    .find('.cc_submenu > ul > li')
    .bind('click',function(){
    var $li_e = $(this);
    //if the menu is already folded,
    //just replace the content
    if(folded){
    hideContent();
    showContent($li_e.attr('class'));
    }
    else //fold and show the content
    fold($li_e);
    });

    El código siguiente corresponde a la definición de la función “m_enter”.

    Quote
    function m_enter(){
    var $this = $(this);
    clearTimeout(menu_time);
    menu_time = setTimeout(function(){
    //img
    $this.find('img').stop().animate({'top':'0px'},400);
    //cc_submenu ul
    $this.find('.cc_submenu > ul').stop().animate({'height':'200px'},400);
    },200);
    }

    El timeout es utilizado para prevenir a este evento si se muevo el ratón de forma rápida por los distintos elementos del menú.

    La función “m_leave” está definida de la siguiente forma:

    Quote
    function m_leave(){
    var $this = $(this);
    clearTimeout(menu_time);
    //img
    $this.find('img').stop().animate({'top':'-600px'},400);
    //cc_submenu ul
    $this.find('.cc_submenu > ul').stop().animate({'height':'0px'},400);
    }

    Cuando pulsemos en el botón de volver al menú, queremos que se lance la función “unfold”.

    Quote
    $('#cc_back').bind('click',unfold);

    La función “fold” solo mostrará el menú de la columna que hayamos seleccionado, y hacemos que el resto de elementos se vayan a la izquierda asignándole el valor de -140 pixels al margin.

    Quote
    function fold($li_e){
    var $item = $li_e.closest('.cc_item');

    var d = 100;
    var step = 0;
    $items.unbind('mouseenter mouseleave');
    $items.not($item).each(function(){
    var $item = $(this);
    $item.stop().animate({
    'marginLeft':'-140px'
    },d += 200,function(){
    ++step;
    if(step == cnt_items-1){
    folded = true;
    showContent($li_e.attr('class'));
    }
    });
    });
    }

    La función “unfold” muestra todos los elementos del menú y también oculta las imágenes y el submenú que estaban siendo mostrados.

    Quote
    function unfold(){
    $('#cc_content').stop().animate({'left':'-700px'},600,function(){
    var d = 100;
    var step = 0;
    $items.each(function(){
    var $item = $(this);

    $item.find('img')
    .stop()
    .animate({'top':'-600px'},200)
    .andSelf()
    .find('.cc_submenu > ul')
    .stop()
    .animate({'height':'0px'},200);

    $item.stop().animate({
    'marginLeft':'0px'
    },d += 200,function(){
    ++step;
    if(step == cnt_items-1){
    folded = false;
    $items.unbind('mouseenter')
    .bind('mouseenter',m_enter)
    .unbind('mouseleave')
    .bind('mouseleave',m_leave);

    hideContent();
    }
    });
    });
    });
    }

    La función para mostrar el contenido de nuestro contenedor a la derecha, asignándole el valor de 140 px a la propiedad left.

    Quote
    function showContent(idx){
    $('#cc_content').stop().animate({'left':'140px'},200,function(){
    $(this).find('.'+idx).fadeIn();
    });
    }

    Por último la función de ocultar el contenido

    function hideContent(){
    $('#cc_content').find('div').hide();
    }
    Para el tema de las fuentes de nuestro menú, nos limitaremos a añadir las siguientes líneas en la cabecera de nuestros html.

    Quote
    <script src="js/cufon-yui.js" type="text/javascript"></script>
    <script src="js/Liberation_Sans.font.js" type="text/javascript"></script>
    <script type="text/javascript">
    Cufon.replace('span');
    Cufon.replace('li');
    Cufon.replace('h1');
    Cufon.replace('p');
    </script>

    La fuente Liberation Sans la puede conseguir en este enlace.

    Una demostración de este menú lo puede ver aquí.

    Descargar


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 40 | 3:36 PM
    Crear un menú con una caja deslizante

    Vamos a crear un menú donde al situarnos por las opciones, el texto se cambiará por una imagen, deslizándose la opción seleccionada para abajo y mostrando más opciones aquellos que tengan opciones añadidas.

    Para conseguir este efecto, haremos uso del plugin para jQuery Easing Plugin.

    Vamos a empezar con el código HTML. Para ello utilizaremos una lista desordenada, colocada de forma horizontal. En esta lista meteremos todos los elementos que tengan nuestro menú. Si además la opción seleccionada tiene un menú extra con otras opciones, entonces le añadimos una capa con esas opciones. La imagen que acompaña a cada opción no se mostrará al principio, sino que se hará una vez que se pase por encima de la opción.

    Quote
    <ul id="sdt_menu" class="sdt_menu">
    <li>
    <a href="#">
    <img src="images/1.jpg" alt=""/>
    <span class="sdt_active"></span>
    <span class="sdt_wrap">
    <span class="sdt_link">Portfolio</span>
    <span class="sdt_descr">My work</span>
    </span>
    </a>
    <div class="sdt_box">
    <a href="#">Websites</a>
    <a href="#">Illustrations</a>
    <a href="#">Photography</a>
    </div>
    </li>
    ...
    </ul>

    Ahora pasemos a la hoja de estilos. Lo primero que hacemos es dar las propiedades a la lista desordenada.

    Quote
    ul.sdt_menu{
    margin:0;
    padding:0;
    list-style: none;
    font-family:"Myriad Pro", "Trebuchet MS", sans-serif;
    font-size:14px;
    width:1020px;
    }

    Desactivamos el text-decoration y outline de todos los enlaces de la lista.

    Quote
    ul.sdt_menu a{
    text-decoration:none;
    outline:none;
    }

    Los elementos “li” de la lista tendrán una posición relativa y estarán colocados a la izquierda.

    Quote
    ul.sdt_menu li{
    float:left;
    width:170px;
    height:85px;
    position:relative;
    cursor:pointer;
    }

    El estilo para el link principal donde tendremos nuestros dos “span” para el título y la descripción serán los siguientes:

    Quote
    ul.sdt_menu li > a{
    position:absolute;
    top:0px;
    left:0px;
    width:170px;
    height:85px;
    z-index:12;
    background:transparent url(../images/overlay.png) no-repeat bottom right;
    -moz-box-shadow:0px 0px 2px #000;
    -webkit-box-shadow:0px 0px 2px #000;
    box-shadow:0px 0px 2px #000;
    }

    Lo siguiente que hacemos es dar los estilos a la imagen. Recordemos que esta estará oculta al principio y que solo aparecerá cuando pasemos por encima de la opción.

    Quote
    ul.sdt_menu li a img{
    border:none;
    position:absolute;
    width:0px;
    height:0px;
    bottom:0px;
    left:85px;
    z-index:100;
    -moz-box-shadow:0px 0px 4px #000;
    -webkit-box-shadow:0px 0px 4px #000;
    box-shadow:0px 0px 4px #000;
    }

    Los estilos para el contenedor del título y de la descripción les daremos los siguientes estilos:

    Quote
    ul.sdt_menu li span.sdt_wrap{
    position:absolute;
    top:25px;
    left:0px;
    width:170px;
    height:60px;
    z-index:15;
    }

    Lo próximo que hacemos es definir los estilos para la caja que se desplaza hacia abajo. Nosotros le asignamos un valor de 0 para la altura y por medio de la animación le indicaremos la altura que se necesita.

    Quote
    ul.sdt_menu li span.sdt_active{
    position:absolute;
    background:#111;
    top:85px;
    width:170px;
    height:0px;
    left:0px;
    z-index:14;
    -moz-box-shadow:0px 0px 4px #000 inset;
    -webkit-box-shadow:0px 0px 4px #000 inset;
    box-shadow:0px 0px 4px #000 inset;
    }

    Los enlaces para los “span” y los enlaces de las cajas serán los siguientes:

    Quote
    ul.sdt_menu li span span.sdt_link,
    ul.sdt_menu li span span.sdt_descr,
    ul.sdt_menu li div.sdt_box a{
    margin-left:15px;
    text-transform:uppercase;
    text-shadow:1px 1px 1px #000;
    }

    Al título y la descripción le daremos los siguientes estilos

    Quote
    ul.sdt_menu li span span.sdt_link{
    color:#fff;
    font-size:24px;
    float:left;
    clear:both;
    }
    ul.sdt_menu li span span.sdt_descr{
    color:#0B75AF;
    float:left;
    clear:both;
    width:155px;
    font-size:10px;
    letter-spacing:1px;
    }

    Pasemos ahora a ver los estilos del submenú el cual estará oculto. Este aparecerá a la izquierda o a la derecha dependiendo de donde estemos.

    Quote
    ul.sdt_menu li div.sdt_box{
    display:block;
    position:absolute;
    width:170px;
    overflow:hidden;
    height:170px;
    top:85px;
    left:0px;
    display:none;
    background:#000;
    }
    ul.sdt_menu li div.sdt_box a{
    float:left;
    clear:both;
    line-height:30px;
    color:#0B75AF;
    }

    Al primer elemento del submenú, de dejamos un margen top.

    Quote
    ul.sdt_menu li div.sdt_box a:first-child{
    margin-top:15px;
    }
    ul.sdt_menu li div.sdt_box a:hover{
    color:#fff;
    }

    Ahora pasaremos a ver el código javascript que le dará la funcionalidad al menú que hemos creado.

    Quote
    $(function() {
    $('#sdt_menu > li').bind('mouseenter',function(){
    var $elem = $(this);
    $elem.find('img')
    .stop(true)
    .animate({
    'width':'170px',
    'height':'170px',
    'left':'0px'
    },400,'easeOutBack')
    .andSelf()
    .find('.sdt_wrap')
    .stop(true)
    .animate({'top':'140px'},500,'easeOutBack')
    .andSelf()
    .find('.sdt_active')
    .stop(true)
    .animate({'height':'170px'},300,function(){
    var $sub_menu = $elem.find('.sdt_box');
    if($sub_menu.length){
    var left = '170px';
    if($elem.parent().children().length == $elem.index()+1)
    left = '-170px';
    $sub_menu.show().animate({'left':left},200);
    }
    });
    }).bind('mouseleave',function(){
    var $elem = $(this);
    var $sub_menu = $elem.find('.sdt_box');
    if($sub_menu.length)
    $sub_menu.hide().css('left','0px');

    $elem.find('.sdt_active')
    .stop(true)
    .animate({'height':'0px'},300)
    .andSelf().find('img')
    .stop(true)
    .animate({
    'width':'0px',
    'height':'0px',
    'left':'85px'},400)
    .andSelf()
    .find('.sdt_wrap')
    .stop(true)
    .animate({'top':'25px'},500);
    });
    });

    Pueden ver un ejemplo aquí.
    Dascargar archivo.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 41 | 4:21 PM
    Crear un menú desplegable utilizando listas y Jquery

    Vamos a ver la forma de crear un menú desplegable elegante utilizando HTML, CSS y un poco de Jquery. En nuestro menú desplegable no hará falta pulsar en el menú para mostrar las opciones, bastará con pasar el ratón por encima del control.

    Los distintos elementos del menú estarán formados por una lista, y cada elemento de la lista será un enlace hacia otra sección.

    La apariencia final del menú, será el de la imagen.

    Lo primero es crear la estructura html del menú.

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

    Con este código, tendremos algo similar a esta imagen.

    Lo siguiente que hacemos es darle algo de estilos.

    Quote
    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 *******/

    Después de añadir estos estilos, el menú quedará de la siguiente forma.

    Por último lo que nos queda es añadirle funcionalidad mediante Jquery. El código sería el siguiente que os indicamos.

    Quote
    //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 es sencillo. Lo primero que hacemos en el código es obtener una referencia hacia nuestro elemento que actuará como menú desplegable. Esto lo almacenamos en la variable “menu”.

    A continuación tenemos el código que hará de controlador de los eventos, y según lo que pase, irá a una función o a otra.

    Si se pasa el ratón por encima de la primera opción del menú, entonces se ejecutará la función “displayOptions”, que mostrará todas las opciones del menú.

    Si el ratón sale del menú, entonces lo que hará será ocultar todos los elementos del menú, excepto el primer elemento que lo volveremos activar.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 42 | 12:31 PM
    Creando un interesante menú de navegación con CSS3

    CSS 3 se está revelando como una poderosa herramienta a la hora de poder hacer diseños mucho más vistosos que los que se podían hacer hasta ahora. Entre las numerosas funcionalidades que nos proporcionará, esta la posibilidad de crear animaciones sin la necesidad de tener que añadir script adicionales.

    El problema actual de utilizar este tipo de propiedades en los diseños, es que no todos los navegadores lo permiten actualmente. Solo Chrome, Safari y Opera permiten actualmente utilizarlo y Firefox, está previsto que lo haga en breve.

    Vamos a ver la forma de crear un menú utilizando estas propiedades de CSS3.

    Pueden ver un ejemplo del menú que crearemos en el siguiente enlace.

    Como vemos el menú consistirá en una barra vertical de iconos, en los cuales según vayamos pasando con el ratón, aparecerá el nombre al que hace referencia ese icono. Si os fijáis, la forma de aparecer y desaparecer se hace de forma degradada.

    Lo primero que hacemos es crear el código HTML, que no es más que una lista con las opciones.

    Quote
    <ul id="navigationMenu">
    <li>
    <a class="home" href="#">
    <span>Home</span>
    </a>
    </li>

    <li>
    <a class="about" href="#">
    <span>About</span>
    </a>
    </li>

    <li>
    <a class="services" href="#">
    <span>Services</span>
    </a>
    </li>

    <li>
    <a class="portfolio" href="#">
    <span>Portfolio</span>
    </a>
    </li>

    <li>
    <a class="contact" href="#">
    <span>Contact us</span>
    </a>
    </li>
    </ul>

    Dentro de cada etiqueta “li”, tendremos un enlace con un “span” dentro, que será lo que mostremos cuando pase el ratón por encima del icono. A cada uno de los enlaces le asignamos un class diferente, para a la hora de mostrar el contenido, solo mostrar el que corresponda y no mostrar otro.

    Ahora pasamos al tema de los estilos. Lo primero que hacemos es dar los estilos básicos al menú. El código correspondiente a esto es el siguiente.

    Quote
    *{
    /* A universal CSS reset */
    margin:0;
    padding:0;
    }

    body{
    font-size:14px;
    color:#666;
    background:#111 no-repeat;

    /* CSS3 Radial Gradients */
    background-image:-moz-radial-gradient(center -100px 45deg, circle farthest-corner, #444 150px, #111 300px);
    background-image:-webkit-gradient(radial, 50% 0, 150, 50% 0, 300, from(#444), to(#111));

    font-family:Arial, Helvetica, sans-serif;
    }

    #navigationMenu li{
    list-style:none;
    height:39px;
    padding:2px;
    width:40px;
    }

    Con estos estilos lo que hacemos es indicarle la fuente que vamos a utilizar, tamaño, fondo...

    La segunda parte del código correspondiente a la hoja de estilos es donde vamos a indicar que la aparición de los textos se haga de una forma escalonada y no de golpe.

    Quote
    #navigationMenu span{
    /* Container properties */
    width:0;
    left:38px;
    padding:0;
    position:absolute;
    overflow:hidden;

    /* Text properties */
    font-family:'Myriad Pro',Arial, Helvetica, sans-serif;
    font-size:18px;
    font-weight:bold;
    letter-spacing:0.6px;
    white-space:nowrap;
    line-height:39px;

    /* CSS3 Transition: */
    -webkit-transition: 0.25s;

    /* Future proofing (these do not work yet): */
    -moz-transition: 0.25s;
    transition: 0.25s;
    }

    #navigationMenu a{
    /* The background sprite: */
    background:url('img/navigation.jpg') no-repeat;

    height:39px;
    width:38px;
    display:block;
    position:relative;
    }

    /* General hover styles */

    #navigationMenu a:hover span{ width:auto; padding:0 20px;overflow:visible; }
    #navigationMenu a:hover{
    text-decoration:none;

    /* CSS outer glow with the box-shadow property */
    -moz-box-shadow:0 0 5px #9ddff5;
    -webkit-box-shadow:0 0 5px #9ddff5;
    box-shadow:0 0 5px #9ddff5;
    }

    Con las propiedades de transición lo que hacemos es que los elementos aparezcan de forma paulatina, en este caso le estamos diciendo que el tiempo que dure hasta que se complete la aparición sea de 250 milisegundo. Por ahora las transiciones solo están disponibles en navegadores que estén basados en WebKit., como son Safari y Chrome.

    Por último, se indican las propiedades que formarán los enlaces que vayan apareciendo según pasamos el ratón por los iconos.

    Quote
    /* Green Button */

    #navigationMenu .home { background-position:0 0;}
    #navigationMenu .home:hover { background-position:0 -39px;}
    #navigationMenu .home span{
    background-color:#7da315;
    color:#3d4f0c;
    text-shadow:1px 1px 0 #99bf31;
    }

    /* Blue Button */

    #navigationMenu .about { background-position:-38px 0;}
    #navigationMenu .about:hover { background-position:-38px -39px;}
    #navigationMenu .about span{
    background-color:#1e8bb4;
    color:#223a44;
    text-shadow:1px 1px 0 #44a8d0;
    }

    /* Orange Button */

    #navigationMenu .services { background-position:-76px 0;}
    #navigationMenu .services:hover { background-position:-76px -39px;}
    #navigationMenu .services span{
    background-color:#c86c1f;
    color:#5a3517;
    text-shadow:1px 1px 0 #d28344;
    }

    /* Yellow Button */

    #navigationMenu .portfolio { background-position:-114px 0;}
    #navigationMenu .portfolio:hover{ background-position:-114px -39px;}
    #navigationMenu .portfolio span{
    background-color:#d0a525;
    color:#604e18;
    text-shadow:1px 1px 0 #d8b54b;
    }

    /* Purple Button */

    #navigationMenu .contact { background-position:-152px 0;}
    #navigationMenu .contact:hover { background-position:-152px -39px;}
    #navigationMenu .contact span{
    background-color:#af1e83;
    color:#460f35;
    text-shadow:1px 1px 0 #d244a6;
    }

    Descargar.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 43 | 5:20 PM
    Menú lateral para mostrar enlaces a otras noticias de forma elegante

    La idea es mostrar una lista fija al lado derecha de la pantalla con una miniatura. Cuando pasemos el ratón sobre estas miniaturas, la imagen se desplazará mostrando el título y dos enlaces, uno para ir al artículo y otro para ir a la demostración.

    Lo primero que hacemos es crear toda la estructura HTML. Para ello utilizaremos listas. Veamos como quedaría esta estructura. Solo ponemos la de una miniatura. El resto serían iguales.

    Quote
    <div id="rp_list" class="rp_list">
    <ul>
    <li>
    <div>
    <img src="images/1.jpg" alt=""/>
    <span class="rp_title">Post Title</span>
    <span class="rp_links">
    <a target="_blank" href="#">Article</a>
    <a target="_blank" href="#">Demo</a>
    </span>
    </div>
    </li>
    ...
    </ul>
    <span id="rp_shuffle" class="rp_shuffle"></span>
    </div>

    En los tag “a”, debemos de poner los enlaces hacia donde queremos que enlace al pulsar.

    Vamos a pasar ahora a ver el tema de la hoja de estilo. Empezamos con los atributos generales de la lista.

    Quote
    .rp_list {
    font-family:Verdana, Helvetica, sans-serif;
    position:fixed;
    right:-220px;
    top:40px;
    margin:0;
    padding:0;
    }

    Como podemos ver, la lista tendrá una posición fija. A la propiedad derecha le damos valor negativo para que oculte las opciones de la lista y solo muestre la miniatura.

    Lo siguiente que hacemos es darle los estilos a la etiqueta “span” que tiene el id “rp_shuffle”.

    Quote
    span.rp_shuffle{
    background:#222 url(../images/shuffle.png) no-repeat 10px 50%;
    width:28px;
    height:14px;
    display:block;
    margin:10px 0px 0px 20px;
    cursor:pointer;
    padding:4px;
    border:1px solid #000;
    -moz-border-radius:5px 0px 0px 5px;
    -webkit-border-bottom-left-radius: 5px;
    -webkit-border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
    border-top-left-radius: 5px;
    }

    La lista tendrá los siguientes estilos:

    Quote
    .rp_list ul{
    margin:0;
    padding:0;
    list-style:none;
    }

    Los elementos de la lista no serán mostrados inicialmente:

    Quote
    .rp_list ul li{
    width: 240px;
    margin-bottom:5px;
    display:none;
    }

    Los estilos de los elementos principales serán los siguientes:

    Quote
    .rp_list ul li div{
    display: block;
    line-height:15px;
    width: 240px;
    height: 80px;
    background:#333;
    border:1px solid #000;
    -moz-border-radius:5px 0px 0px 5px;
    -webkit-border-bottom-left-radius: 5px;
    -webkit-border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
    border-top-left-radius: 5px;
    }

    Las miniaturas tendrán un tamaño de 70 x 70 pixel y le añadiremos una sombra a la caja:

    Quote
    .rp_list ul li div img{
    width:70px;
    border:none;
    float:left;
    margin:4px 10px 0px 4px;
    border:1px solid #111;
    -moz-box-shadow:1px 1px 3px #000;
    -webkit-box-shadow:1px 1px 3px #000;
    box-shadow:1px 1px 3px #000;
    }

    El estilo para la clase rp_title es el siguiente:

    Quote
    span.rp_title{
    font-size:11px;
    color:#ddd;
    height:46px;
    margin:4px 0px 0px 20px;
    display:block;
    text-shadow:1px 1px 1px #000;
    padding-top:3px;
    background:#222;
    -moz-box-shadow:0px 0px 5px #000 inset;
    -webkit-box-shadow:0px 0px 5px #000 inset;
    box-shadow:0px 0px 5px #000 inset;
    }

    El siguiente código corresponde al estilo de los links y los botones:

    Quote
    span.rp_links{
    width:195px;
    height:8px;
    padding-top:2px;
    display:block;
    margin-left:42px;
    }
    span.rp_links a{
    background: #222 url(../images/bgbutton.png) repeat-x;
    padding: 2px 18px;
    font-size:10px;
    color: #fff;
    text-decoration: none;
    line-height: 1;
    -moz-box-shadow: 0 1px 3px #000;
    -webkit-box-shadow: 0 1px 3px #000;
    box-shadow:0 1px 3px #000;
    text-shadow: 0 -1px 1px #222;
    cursor: pointer;
    outline:none;
    }
    span.rp_links a:hover{
    background-color:#000;
    color:#fff;
    }

    Con esto terminamos el tema de los estilos, y nos ponemos ahora con el código JavaScript que le dará funcionalidad a nuestro menú latera.

    La idea del código es que los elementos del menú solo muestren las miniaturas, y que al pasar por ellos, se desplacen mostrando completamente el elemento, junto con los enlaces y el botón.

    Las función de shuffle, nos mostrará de forma aleatoria los post.

    El código jQuery correspondiente es el siguiente:

    Quote
    $(function() {
    /**
    * the list of posts
    */
    var $list = $('#rp_list ul');
    /**
    * number of related posts
    */
    var elems_cnt = $list.children().length;
    /**
    * show the first set of posts.
    * 200 is the initial left margin for the list elements
    */
    load(200);
    function load(initial){
    $list.find('li').hide().andSelf().find('div').css('margin-left',-initial+'px');
    var loaded = 0;
    //show 5 random posts from all the ones in the list.
    //Make sure not to repeat
    while(loaded < 5){
    var r = Math.floor(Math.random()*elems_cnt);
    var $elem = $list.find('li:nth-child('+ (r+1) +')');
    if($elem.is(':visible'))
    continue;
    else
    $elem.show();
    ++loaded;
    }
    //animate them
    var d = 200;
    $list.find('li:visible div').each(function(){
    $(this).stop().animate({
    'marginLeft':'-50px'
    },d += 100);
    });
    }
    /**
    * hovering over the list elements makes them slide out
    */
    $list.find('li:visible').live('mouseenter',function () {
    $(this).find('div').stop().animate({
    'marginLeft':'-220px'
    },200);
    }).live('mouseleave',function () {
    $(this).find('div').stop().animate({
    'marginLeft':'-50px'
    },200);
    });
    /**
    * when clicking the shuffle button,
    * show 5 random posts
    */
    $('#rp_shuffle').unbind('click')
    .bind('click',shuffle)
    .stop()
    .animate({'margin-left':'-18px'},700);
    function shuffle(){
    $list.find('li:visible div').stop().animate({
    'marginLeft':'60px'
    },200,function(){
    load(-60);
    });
    }
    });

  • Demo
  • Descargar


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
  • GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 44 | 3:03 PM
    Cómo crear un menú de pestañas elegante en jQuery

    En esta ocasión, aprenderemos a crear un menú de pestañas con nuestra querida librería de javascript jQuery. Recrearemos de forma simple y limpia un menú de pestañas elegante, útil y listo para utilizar en nuestros sitios web.

  • Mirar demo
  • Descarga

    Introducción: ¿Qué vamos a hacer?
    Cada día existen más diseños inspirados en el “formato blog”, estructuras que en su mayoría se componen de una cabecera, un menú horizontal, una división del contenido a dos columnas: contenido del artículo y columna derecha de widgets / gadgets y finalmente termina en un pie de página.

    Es en esa columna derecha, en la de widgets, donde podemos ver un gran uso del menú de pestañas, la mayoría de las veces son pestañas que contienen información sobre el archivo de publicaciones, últimos comentarios, artículos más leídos, etc. Os dejo con una imagen previa de lo que haremos:

    Así pues, mediante un poco de XHTML, CSS y javascript (jQuery en este caso) aprenderemos a crear nuestro propio menú de pestañas listo para usar en cualquiera de nuestros diseños web.

    ¡Vamos a ello!

    Paso 1: La estructura HTML
    Como siempre, lo primero que debemos tener claro y preparado para trabajar, es la estructura html que tendrá nuestra página. En esta ocasión tendrán especial relevancia las listas y bloques de contenido:

    Quote
    <!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="main.css" type="text/css" media="screen" />
    <!--[if IE]>
    <link rel="stylesheet" href="ie.css" type="text/css" media="screen" />
    <![endif]-->
    </head>
    <body>
    <div class="wrapper">
    <h1>Cómo crear un menú de pestañas elegante en jQuery</h1>
    <br />
    <div class="aux">
    <div id="container">
    <ul class="menu">
    <li id="noticias" class="active">Noticias</li>
    <li id="tutoriales">Tutoriales</li>
    <li id="enlaces">Enlaces</li>
    </ul>
    <span class="clear"></span>
    <div class="content noticias">
    <h3>Últimas Noticias</h3>
    <ul>
    <li><img src="img/bullet.png" alt="-" /> Manifiesto por los Derechos en Internet </li>
    <li><img src="img/bullet.png" alt="-" /> Logos que Inspiran Volumen #5</li>
    <li><img src="img/bullet.png" alt="-" /> Erasmusu llega a los 6.000 usuarios</li>
    <li><img src="img/bullet.png" alt="-" /> Lanzamos web.ontuts.com!</li>
    </ul>
    </div>
    <div class="content tutoriales">
    <h3>Últimos Tutoriales</h3>
    <ul>
    <li><img src="img/bullet.png" alt="-" /> Cómo crear bordes redondeados en CSS3</li>
    <li><img src="img/bullet.png" alt="-" /> JSONP, llamadas entre dominios</li>
    <li><img src="img/bullet.png" alt="-" /> Introducción a Microsoft Silverlight</li>
    <li><img src="img/bullet.png" alt="-" /> Cómo aplicar sombra en textos con CSS3</li>
    <li><img src="img/bullet.png" alt="-" /> Creando capa de conexión abstracta a base de datos con PHP</li>
    <li><img src="img/bullet.png" alt="-" /> Mini Aplicaciones Web con Python y Juno</li>
    </ul>
    </div>
    <div class="content enlaces">
    <h3>Deberías Visitar...</h3>
    <ul>
    <li><img src="img/bullet.png" alt="-" /> <a href="http://www.plusmusica.com">www.plusmusica.com</a> - Online jukebox!</li>
    <li><img src="img/bullet.png" alt="-" /> <a href="http://www.cokidoo.com">www.cokidoo.com</a> - Nuestra startup! <img src="http://web.ontuts.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"> </li>
    <li><img src="img/bullet.png" alt="-" /> <a href="http://www.cokidoo.com">www.pixelartgames.com</a> - Te gustan los juegos pixel art? <img src="http://web.ontuts.com/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley"> </li>
    <li><img src="img/bullet.png" alt="-" /> <a href="http://www.dmsconsulting.es">www.dmsconsulting.es</a> - Anterior empresa</li>
    </ul>
    </div>
    </div>
    </div>
    </div>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="tabs.js"></script>
    </body>
    </html>

    Estamos utilizando un contenedor con el id “container“, el cual fija el ancho de nuestro widget y que contiene por un lado el menú de selección de pestaña activa (en forma de lista desordenada) y tres divisiones contenedoras:

    • noticias
    • tutoriales
    • enlaces

    Estas tres divisiones (como habréis podido deducir) son las tres secciones que tendrá nuestro widget, las cuales contendrán su información correspondiente y que comparten la clase de CSS “content“.

    Cada sección del menú horizontal tiene un ID que se corresponde con la clase de cada contenedor “content”. Esto nos facilitará el código javascript en próximos pasos.

    Esta estructura html que parece tan simple, nos ayudará mucho en el paso 3, cuando tengamos que aplicar el javascript para recrear así la funcionalidad del menú.

    Paso 2: Aplicando estilo a nuestro menú de pestañas
    Como hemos visto en la imagen previa, queremos que nuestro menú tenga las siguientes características de estilo:
    Menú horizontal para las pestañas.
    Ocultado de secciones no activas.
    Resaltado de sección activa para diferenciarse de las demás.
    Algunas zonas redondeadas para mejorar un poco el aspecto visual.

    Para ello, aplicaremos el siguiente código CSS:

    Quote
    /******* MENU *******/
    #container{
    margin:4em auto;
    width:400px;
    }
    #container ul{
    list-style:none;
    list-style-position:outside;
    }
    #container ul.menu li{
    float:left;
    margin-right:8px;
    margin-bottom:-1px;
    }
    #container ul.menu li{
    font-weight:700;
    display:block;
    padding:10px 15px;
    background:#303030;
    margin-bottom:-1px;
    border:1px solid #3e3e3e;
    border-width:1px 1px 1px 1px;
    position:relative;
    color:#e4e1cd;
    cursor:pointer;
    border-radius:3px 3px 0 0;
    -moz-border-radius:3px 3px 0 0;
    -webkit-border-radius:3px 3px 0 0;
    }
    #container ul.menu li:hover{
    color:#fff;
    }
    #container ul.menu li.active{
    background:#171717;
    top:1px;
    border-bottom:0;
    color:#fff;
    }
    /******* /MENU *******/

    /******* CONTENT *******/
    .content{
    margin:0pt auto;
    background:#efefef;
    background:#171717;
    border:1px solid #3e3e3e;
    text-align:left;
    padding:1.3em;
    padding-bottom:20px;
    font-size:12px;
    line-height:2em;
    color:#8C8C8C;
    border-radius:0 5px 5px 5px;
    -moz-border-radius:0 5px 5px 5px;
    -webkit-border-radius:0 5px 5px 5px;
    }
    .content h3{
    line-height:1em;
    vertical-align:middle;
    height:48px;
    padding:10px 10px 10px 52px;
    font-size:32px;
    color:#E4E1CD;
    }
    /******* /CONTENT *******/

    /******* NOTICIAS *******/
    .content.noticias h3{
    background:transparent url(img/news.png) no-repeat scroll left top;
    }
    .content.noticias{
    display:block;
    }
    /******* /NOTICIAS *******/

    /******* TUTORIALES *******/
    .content.tutoriales h3{
    background:transparent url(img/tuts.png) no-repeat scroll left top;
    }
    .content.tutoriales{
    display:none;
    }
    /******* /TUTORIALES *******/

    /******* ENLACES *******/
    .content.enlaces h3{
    background:transparent url(img/links.png) no-repeat scroll left top;
    }
    .content.enlaces{
    display:none;
    }
    .content.enlaces a{
    color:#498BBF;
    }
    /******* /ENLACES *******/

    Como véis, estamos presuponiendo que todas las secciones de contenido estarán ocultas mediante la propiedad CSS “display:none“, salvo la sección de “noticias” la cual estará visible y activa asignándole la propiedad “display:block“. A su vez, en el menú “noticias” tendrá la clase “active” asignada, indicando que es la sección actualmente activa.

    La clase de CSS “active” baja en 1 pixel la altura de la pestaña activa y oculta la línea superior de la división del contenido, proporcionando un poco más de diferenciación frente al resto de pestañas inactivas.

    Sin la clase active y las propiedadas mencionadas, ocurriría lo siguiente:

    Otra forma o camino a seguir para ocultar esta línea, sería aplicar un color idéntico al fondo de la división contenedora al borde inferior de la sección del menú, es decir que la clase “active” quedaría así:

    Quote
    #container ul.menu li.active{
    background:#171717;
    top:1px;
    border-bottom:0;
    color:#fff;
    }

    El resto de código CSS simplemente se basa en retoques visuales para lograr un menú de pestañas un poco más bonito: imágenes para los encabezados, bordes redondeados, etc.

    No queda mucho más que comentar, así que… ¡Vamos a por el código javascript!

    Paso 3: Añadiendo funcionalidad con javascript y jQuery
    Antes de añadir la funcionalidad, es importante pensar con calma y dejar muy claro qué es lo que queremos conseguir y cuáles serán los efectos a emplear. En nuestro caso recrearemos lo siguiente:

    • Las secciones del menú activan los contenidos
    • Al hacer click en una sección, se oculta el contenido actual y se muestra el nuevo.
    • Al hacer click en una sección, esta pasa a estar activa, la anterior deja de estarlo.
    • Utilizaremos para alternar entre contenidos un “efecto fade in“.

    Para lograr todo esto, nos será de gran ayuda los métodos addClass y removeClass que nos proporciona jQuery, con los cuales podremos aplicar o quitar estilo de CSS de forma rápida y cómoda. Este sería el código de javascript:

    Quote
    $(document).ready(function(){
    $(".menu > li").click(function(e){
    var a = e.target.id;
    //desactivamos seccion y activamos elemento de menu
    $(".menu li.active").removeClass("active");
    $(".menu #"+a).addClass("active");
    //ocultamos divisiones, mostramos la seleccionada
    $(".content").css("display", "none");
    $("."+a).fadeIn();
    });
    });

    Es realmente poco código, ¿verdad? Esto tiene una explicación bastante clara, para los que no lo hayáis deducido ya, lo explicamos:
    Cada sección en el menú tiene un ID asignado.
    Cada contenedor “content” tiene además una clase asignada, que coincide con el ID de la sección del menú.
    • b>Mediante el ID, conocemos qué sección está seleccionando el usuario, y lo guardamos en una variable.
    • Con esa variable, accedemos a los distintos selectores para aplicar las clases correspondientes.
    • La clase “active” nos permite también saber qué sección dejará de estar activa.

    De no organizarlo o plantearlo de esta forma en la que reaprovechamos una cadena para crear distintos selectores, estaríamos ahora mismo trabajando con un código javascript de muchísimas más líneas, ya que tendríamos que generar código para cada una de las secciones que tengamos, a más secciones más y más código necesitaríamos.

    El método fadeIn() lo que hace es quitar el estilo por defecto “display:none” que tienen las secciones ocultas y lo muestra de forma progresiva.

    Una vez más se demuestra lo importante que es el planteamiento inicial, tanto de estructura HTML, como de CSS y javascript para lograr el objetivo final con el mínimo de código y peso posible.

    Reflexión final
    Es realmente interesante ver como jQuery ha facilitado la vida a los desarrolladores web con ejemplos como este, en los que reutilizando una cadena de texto sacada apartir de un ID podremos generar múltiples selectores listos para utilizar y trabajar con ellos, ahorrándonos código y aportando mayor rendimiento y velocidad a nuestras páginas / scripts.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
  • GUARAGUAO
    Mensajes: 2362
    Reputación: 81
    Mensaje Nº 45 | 4:39 PM
    Cómo crear un Menú Contextual en Javascript mediante jQuery

    A medida que avanzamos en el tiempo, las aplicaciones web van cobrando mayor funcionalidad hasta el punto de llegar a ser réplicas exactas de algunas de las aplicaciones de escritorio más conocidas (Google Docs, Zoho…). Todo esto se consigue mediante el uso de técnicas de CSS y Javascript “innovadoras”, recreando controles tan típicos pero ausentes hasta ahora como es el caso del menú contextual, el cual recrearemos en este tutorial.

    Mirar demo
    Descarga

    Introducción: ¿Qué vamos a hacer?
    Vivimos en una época en cual las aplicaciones web ganan en usabilidad e interactividad a una velocidad pasmosa. Si hace unos años el Javascript se utilizaba principalmente para crear formularios un poco más interactivos y algunas pequeñas alertas, ahora el Javascript y el CSS nos permiten mucho más, y se están utilizando para recrear auténticas interfaces ricas, funcionales y usables para la mayoría de los navegadores.
    En este tutorial aprenderemos a crear paso a paso y desde cero el famoso menú contextual de los distintos sistemas operativos, el cual se activa cuando el usuario hace click con el botón secundario de su ratón.

    Nuestro menú contextual soportará:
    • Elementos de tipo enlace
    • Elementos que desencadenan acciones
    • Elementos desactivados (aparecen, pero no se podrán seleccionar)
    Aparecerá cuando el usuario pinche el botón secundario de su ratón.
    Desaparecerá cuando el usuario pinche fuera del mismo, en alguna de las opciones activas o cuando se presione la tecla Escape.

    Para ello utilizaremos lo mismo que venimos usando en la mayoría de los tutoriales que os he presentado: la librería de javascript jQuery, CSS y HTML.

    Paso 1: La estructura
    El documento HTML que utilizaremos será bastante sencillo, utilizaremos la misma base que en otras ocasiones y un pequeño menú en forma de lista desordenada. Os dejo con el código para que le echéis un vistazo:

    Quote
    <!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>Creando un menu contextual mediante jQuery | Web.Ontuts</title>
    <link rel="stylesheet" href="main.css" type="text/css" media="screen" />
    </head>
    <body>
    <div class="wrapper">
    <div class="section">
    <h1>Utiliza el boton derecho del ratón para activar el menú contextual</h1>
    </div>
    </div>

    <div id="menu">
    <ul>
    <li id="menu_anterior">Anterior</li>
    <li id="menu_siguiente" class="disabled">Siguiente</li>
    <li id="menu_recargar">Recargar</li>
    <li id="menu_web"><a href="http://web.ontuts.com">Visitar web.ontuts</a></li>
    <li id="menu_favoritos">Agregar a favoritos...</li>
    </ul>
    </div>

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="menu.js"></script>
    </body>
    </html>

    El menú contextual, representado con una lista desordenada tiene los siguientes elementos:
    Anterior: Regresa a la página anterior
    Siguiente: Deshabilitado
    Recargar: Recarga la página actual
    Visitar web.XXX: Enlace que lleva a web.XXX.com
    Agrevar a favoritos…: Abre el diálogo de agregado a favoritos

    Cada elemento de la lista desordenada de id=”menu” representa cada una de las opciones del menú. Todas contienen un id que nos servirá posteriormente para detectar su selección. La clase “disabled” del elemento “Siguiente” indica que está deshabilitado.
    Los elementos del menú tienen un id asociado para reconocer su selección. La clase “disabled” indica que la opción está deshabilitada.

    Una vez tenemos claro qué hará cada opción de nuestro menú, sólo nos queda gestionar todo este comportamiento mediante Javascript, pero antes y como de costumbre, vamos a echar un vistazo rápido al código CSS que hemos utilizado.

    Paso 2: Añadiendo estilo con CSS a nuestro menú contextual
    En este caso, el código CSS es muy básico y sólo hay un par de puntos a resaltar, echemos un vistazo al código antes de resaltar dichos puntos:

    Quote
    @CHARSET "UTF-8";
    /*
    Author: Adrian Mato
    Author URI: http://www.yensdesign.com & 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:baselinebaseline;
    }
    body{
    line-height: 1em;
    font-size: 12px;
    background: #262626 url(img/bg.png) repeat scroll 0 0;
    font-family: Myriad Pro, Arial, Helvetica, sans-serif;
    margin: 0pt;
    cursor: default;
    }
    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: #296ba5;
    text-decoration: none;
    outline: none !Important;
    }
    html,body{
    height:100%;
    }
    .clear{
    clear: both;
    height: 0;
    visibility: hidden;
    display: block;
    line-height: 0;
    }
    .clearfix{
    overflow: hidden;
    }
    .fleft{
    float: left;
    }
    .fright{
    float: rightright;
    }
    .italic{
    font-style: italic;
    }
    /******* /GENERAL RESET *******/

    /******* CONTENT *******/
    .wrapper{
    width: 800px;
    margin: 0pt auto;
    padding-top: 50px;
    }
    h1{
    color: #fff;
    font-size: 18px;
    line-height: 3em;
    }
    .section{
    margin-bottom: 25px;
    }
    /******* /CONTENT *******/

    /******* MENU *******/
    #menu{
    display: none;
    width: 165px;
    padding: 6px;
    background: #171717;
    border: 1px solid #3e3e3e;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
    position: absolute;
    }
    #menu ul{
    font-family: Tahoma, Arial, Helvetica, sans-serif;
    color: #6d6d6d;
    background: #fff;
    border: 1px solid #171717;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
    }
    #menu ul li{
    line-height: 1.5em;
    padding: 5px 5px 5px 25px;
    font-size: 11px;
    border-bottom: 1px solid #fff;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
    }
    #menu ul li:hover{
    background-color: #fff8cc;
    border-bottom: 1px solid #ffe222;
    color: #000;
    cursor: pointer;
    }
    #menu ul li a{
    color: #6d6d6d;
    display: block;
    }
    #menu ul li.disabled, #menu ul li.disabled a{
    color: #bbbbbb;
    cursor: default;
    }
    #menu ul li.disabled:hover{
    background: #fff;
    border-bottom: 1px solid #fff;
    }
    #menu ul li{
    background-position: 3px 6px;
    background-repeat: no-repeat;
    }
    #menu ul li#menu_anterior{
    background-image: url(img/anterior.png);
    }
    #menu ul li#menu_recargar{
    background-image: url(img/refresh.png);
    }
    #menu ul li#menu_web{
    background-position: 3px 5px;
    background-image: url(img/web.png);
    }
    #menu ul li#menu_favoritos{
    background-image: url(img/fav.png);
    }
    /******* /MENU *******/

    Para los más despistados me gustaría recordaros que estamos utilizando una serie de propiedades que no se consideran estándar, se trata de una serie de propiedades enfocadas a recrear el redondeado de los bordes de nuestro menú contextual, hablamos de las propiedades:

    -moz-border-radius: Para navegadoresmozilla
    -webkit-border-radius: Para navegadores webkit
    -khtml-border-radius: Para el navegador Konqueror

    La propiedad CSS estándar border-radius permite definir el radio de los bordes redondeados de nuestros elementos. Debido a que algunos navegadores todavía no soportan de forma oficial el redondeado, se utilizan propiedades no estándar como: -moz-border-radius, -webkit-border-radius o -khtml-border-radius.

    Si os habéis fijado, también estamos definiendo una imagen de fondo para todos los elementos del menú, salvo para la opción deshabilitada “Siguiente”. Es algo estético, pero dotará de mayor vistosidad a nuestro menú contextual.

    Ahora sí, vamos a por la funcionalidad de nuestro menú, ¡vamos a la parte de javascript con jQuery!

    Paso 3: Dándole vida y funcionalidad a nuestro menú contextual mediante Javascript
    Hemos dejado pasar por alto un pequeño detalle en la sección del CSS que me gustaría comentaros ahora. El menú contextual tiene por defecto aplicada la propiedad de CSS “display: none“, con ello conseguimos que el menú esté oculto hasta que el usuario lo llame mediante el botón secundario de su ratón.

    El menú contextual está por defecto oculto mediante CSS (display: none), alterando esta propiedad mediante javascript haremos que se muestre donde el usuario haga click.

    Vamos a definir y recordar de forma breve qué es lo que hará nuestro menú contextual:
    Aparecerá cuando el usuario haga click con el botón secundario de su ratón.
    Desaparecerá cuando el usuario seleccione una opción, pinche fuera del menú contextual o presione la tecla Escape.

    Vamos a abordar las distintas partes del código de nuestro menu.js, pero recordad que todo este código irá como siempre dentro del evento $(document).ready. Es decir:

    Quote
    //Cuando el documento esté listo...
    $(document).ready(function(){
    //todo el código aquí
    )};

    Aclarado esto, vamos a ello.

    Desactivando el menú contextual por defecto
    Como bien sabréis, al pinchar en el botón secundario de vuestro ratón en una web se muestra por defecto un menú contextual correspondiente al navegador. Mediante la función bind de jQuery vamos a cancelar este menú contextual, en pro de mostrar nuestro propio menú contextual personalizado.

    Mediante la función bind de jQuery cancelaremos el menú contextual por defecto. Esto funciona en la mayoría de navegadores pero el navegador Opera no lo admite, por lo que se seguirá mostrando el menú contextual por defecto.

    Con este sencillo código cancelaremos el menú contextual por defecto y además mostraremos nuestro menú contextual:

    Quote
    //EVITAMOS que se muestre el MENU CONTEXTUAL del sistema operativo al hacer CLICK con el BOTON DERECHO del RATON
    $(document).bind("contextmenu", function(e){
    menu.css({'display':'block', 'left':e.pageX, 'top':e.pageY});
    return false;
    });

    Como podréis leer en los comentarios del código de arriba, estamos alterando varias propiedades del CSS para mostrar correctamente nuestro menú. Modificando la propiedad display: block del CSS estamos mostrando la división que contiene a nuestro menú contextual.

    Además estamos situando el menú de forma que la esquina superior izquierda, coincide con donde el usuario hace click.

    El objeto “e” devuelto por la función bind permite reconocer la posición exacta del click del usuario. Las propiedades e.pageX y e.pageY nos dicen la distancia horizontal y vertical (respectivamente) que hay en pixels desde la esquina superior izquierda (punto 0,0).
    Ahora que ya sabemos mostrar nuestro menú contextual, vamos a ver cómo gestionar las acciones de los elementos del menú.

    Controlando las acciones de los elementos del menú contextual
    Vamos a utilizar una sentencia del tipo switch, de esta forma controlaremos para cada caso / opción del menú contextual las acciones que deseemos, y además será muy fácil añadir nuevas acciones a futuros elementos nuevos:

    Quote
    //variables de control
    var menuId = "menu";
    var menu = $("#"+menuId);

    //Control sobre las opciones del menu contextual
    menu.click(function(e){
    //si la opcion esta desactivado, no pasa nada
    if(e.target.className == "disabled"){
    return false;
    }
    //si esta activada, gestionamos cada una y sus acciones
    else{
    switch(e.target.id){
    case "menu_anterior":
    history.back(-1);
    break;
    case "menu_siguiente":
    alert("ha seleccionado siguiente");
    break;
    case "menu_recargar":
    document.location.reload();
    break;
    case "menu_favoritos":
    var title = "Tutoriales de Desarrollo y Diseño Web | Web.Ontuts";
    var url = "http://web.ontuts.com";
    //para firefox
    if(window.sidebar)
    window.sidebar.addPanel(title, url, "");
    //para Internet Explorer
    else if(window.external)
    window.external.AddFavorite(url, title);
    break;
    }
    menu.css("display", "none");
    }
    });

    Como véis, estamos guardando en dos variables dos referencias al menú, simplemente y como hacemos siempre para optimizar un poco el código y evitar que jQuery busque el elemento cada vez que se ejecuta el código javascript.

    Mediante la función click de nuestro menú contextual sabremos en todo momento cuándo se está haciendo click en alguna de las opciones del menú, para poder decidir en cada caso qué hacer. ¿Cómo sabemos cuál ha sido seleccionada? Muy fácil: el objeto “e” de la función click nos permitirá explorar el elemento en el cual se ha hecho click y además, conocer su id.

    Nuevamente el objeto “e” (de la función click) nos permitirá reconocer el elemento del menú que se ha seleccionado. Según el valor del id del elemento, ejecutaremos unas acciones u otras.

    En caso de que el elemento seleccionado tenga asignada la clase CSS “disabled” sabremos que esta opción está desactivada y no ocurrirá absolutamente nada (ni si quiera se cerrará el menú contextual).

    Las acciones de los elementos son triviales, así que os dejo que investiguéis un poco vosotros mismos, pero los nombres son muy sugerentes.

    Ocultando el menú contextual
    La lógica nos dice que el menú contextual y su comprobación de ocultado sólo tendríamos que aplicarla cuando el menú estuviese visible, pero en nuestro caso, no necesitamos gestionar el estado del menú, ya que variando las propiedades de CSS será suficiente.

    Los dos casos en los que debería desaparecer el menú contextual serían:
    • Usuario hace click en alguna zona de la página que no sea el menú
    • Si el usuario pulsa la tecla Escape
    • Habría un tercer caso, que hemos puesto antes, que sería cuando se ha seleccionado una opción del menú activada (en las deshabilitadas no se oculta).

    He aquí los dos casos que acabamos de comentar:

    Quote
    //controlamos ocultado de menu cuando esta activo
    //click boton principal raton
    $(document).click(function(e){
    if(e.button == 0 && e.target.parentNode.parentNode.id != menuId){
    menu.css("display", "none");
    }
    });
    //pulsacion tecla escape
    $(document).keydown(function(e){
    if(e.keyCode == 27){
    menu.css("display", "none");
    }
    });

    Nuevamente el objeto “e” en las dos funciones utilizadas nos permiten acceder[b] a las propiedades [b]button y keyCode para saber qué botón y tecla se ha pulsado, en nuestro caso el botón principal y la tecla Escape. También es interesante ver cómo vamos accediendo desde el elemento sobre el que se ha hecho click, hasta el elemento padre “menu” mediante “e.target.parentNode.parentNode.id, de esta forma podremos comprobar si se el usuario ha pinchado encima / dentro de alguna parte del menú contextual.”

    La propiedad button con valor 0 nos indica que se está pulsando el botón principal del ratón. La propiedad keyCode con valor 27 indica que se ha pulsado la tecla Escape. Ambas propiedades provienen del objeto “e” de sus respectivas funciones.

    Y esto es todo lo que hemos de tener en nuestro código javascript… una vez más es menos de lo que en un principio pudiese parecer.

    Reflexión final
    Ahora que sabemos cómo crear las bases para nuestro menú contextual sólo queda pensar en formas de mejorarlo, por ejemplo, si un usuario pincha en la parte de la derecha de la pantalla, se activaría el scroll horizontal, seguramente fuese conveniente detectarlo y mostrar un poco más a la izquierda el menú, etc…

    Hemos retomado por mi parte los tutoriales con javascript y jQuery, la verdad es que me encanta escribir sobre estos tutoriales, son detalles y pequeñas mejoras que dan mucha calidad a las aplicaciones. Seguramente siga profundizando en distintos tipos de controles para tratar de recrear interfaces ricas y útiles para vuestros proyectos.


    Las vírgenes tienen muchas navidades pero ninguna Nochebuena.
    Foro uCoz » Ayuda a los webmasters » Configuración del diseño » Menús (escribimos aquí sobre la cosa)
    Búscar: