he hecho un menú desplegable
por si os puede ser de ayuda, he hecho una función que, usando el DOM, controla un menú realizado con "ul" independientemente del número de opciones en cada nivel. lo he probado hasta un tercer nivel, pero ampliarlo a más creo que sería fácil.
pegas: independizarlo del número de niveles y que no funciona bien en Opera. se admiten test en navegadores de Mac y mejoras.
javascript:
<code>
function compruebaMenu(opcion) {
var nodo = document.getElementById('menu').getElementsByTagName('ul').item(0).getElementsByTagName('ul');
for (i=0;i<nodo.length;i++) {
if ((nodo.item(i).id == opcion) || ((nodo.item(i).getElementsByTagName('ul').length != 0) && (nodo.item(i).getElementsByTagName('ul').namedItem(opcion) != null))) {
nodo.item(i).style.display = 'block';
} else {
nodo.item(i).style.display = 'none';
}
}
}
</code>
html
<code>
<div id="menu">
<ul>
<li><a href="#" onclick="compruebaMenu('gestionOfertas');return false;" title="Gestión de ofertas" accesskey="1" rel="section">Gesti&oacute;n de ofertas</a>
<ul id="gestionOfertas">
<li><a href="#" onclick="return false;" title="Nueva oferta" rel="section">Nueva oferta</a></li>
<li><a href="#" onclick="return false;" title="Listado ofertas en edición" rel="section">Listado ofertas en edici&oacute;n</a></li>
<li><a href="#" onclick="return false;" title="Listado ofertas edición cerrada" rel="section">Listado ofertas edición cerrada</a></li>
<li><a href="#" onclick="return false;" title="Listado ofertas publicadas" rel="section">Listado ofertas publicadas</a></li>
<li><a href="#" onclick="return false;" title="Listado ofertas terminadas" rel="section">Listado ofertas terminadas</a></li>
</ul>
</li>
<li><a href="#" onclick="compruebaMenu('gestionAvisos');return false;" title="Gestión de avisos" accesskey="2" rel="section">Gesti&oacute;n de avisos</a>
<ul id="gestionAvisos">
<li><a href="#" onclick="return false;" title="Nuevo" rel="section">Nuevo</a></li>
<li><a href="#" onclick="return false;" title="Listado avisos" rel="section">Listado avisos</a></li>
</ul>
</li>
<li><a href="#" onclick="compruebaMenu('reclutamiento');return false;" title="Reclutamiento" accesskey="3" rel="section">Reclutamiento</a>
<ul id="reclutamiento">
<li><a href="#" onclick="compruebaMenu('descargaSolicitudes');return false;" title="" rel="section">Descarga de solicitudes</a>
<ul id="descargaSolicitudes">
<li><a href="#" onclick="return false;" title="" rel="section">Programar descargas</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Ejecutar descargas</a></li>
</ul>
</li>
<li><a href="#" onclick="compruebaMenu('filtrado');return false;" title="" rel="section">Filtrado</a>
<ul id="filtrado">
<li><a href="#" onclick="return false;" title="" rel="section">B&uacute;squeda general</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Definir requisitos b&aacute;sicos</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Recuperar requisitos b&aacute;sicos</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Recuperar listado</a></li>
</ul>
</li>
<li><a href="#" onclick="compruebaMenu('valoracion');return false;" title="" rel="section">Valoraci&oacute;n</a>
<ul id="valoracion">
<li><a href="#" onclick="return false;" title="" rel="section">Definir criterios</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Recuperar criterios</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Valorar listado</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Recuperar listado valorado</a></li>
<li><a href="#" onclick="return false;" title="" rel="section">Fotos TCP's</a></li>
</ul>
</li>
<li><a href="#" onclick="compruebaMenu('preseleccion');return false;" title="" rel="section">Preselecci&oacute;n</a>
<ul id="preseleccion">
<li><a href="#" onclick="return false;" title="" rel="section">Recuperar listado</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#" onclick="return false;" title="Selección" accesskey="4" rel="section">Selecci&oacute;n</a></li>
<li><a href="#" onclick="return false;" title="Contratación" accesskey="5" rel="section">Contrataci&oacute;n</a></li>
</ul>
</div>
</code>
css (aquí lo que querais, lo pongo por pijería :P)
<code>
#body {
margin: 0;
padding: 0;
font-family: Georgia, Tahoma, Verdana, Arial, Helvetica, Geneva, sans-serif;
font-size: 70%;
}
#menu ul {
margin: 0;
padding: 0;
list-style: none;
}
#menu ul ul {
margin-left: 20px;
display: none;
}
#menu a {
color: #339933;
text-decoration: none;
}
#menu a:hover {
color: #ffffff;
background-color: #339933;
}
</code>
zigotica
cbp, mirate mas ejemplos, tu codigo es muy corto pero haces trampa añadiendo los eventos y los id en el onclick del html :)
el ejemplo que mas me gusta hasta ahora es el de kryogenix
basicamente va mirando en la lista por nodos que sean elementos (ul, li, a) y si son ul buscas de nuevo poniendo ese ul como argumento de la funcion. se puede hacer de varias maneras pero ese enfoquee me gusta bastante.
XrV
las listas yo creo que son la mejor manera de ordenar un menú, es la cosa más accesible que hay :)
estoy con zigotico cbp, haces trampas :P
cbp
joer, me habeis llamado tramposo, con lo que me jode :evil:
pero no os falta razón, esto lo hice para una cosa concreta y sin mucho tiempo, lo he puesto por si podía servir de punto de partida para hacer algo mejor.
pero hala hala, ios con vuestro amigo kryogenix, venga...
:P
marcus
a los tres......estoy bastante pez en javascript, y adapté un menu hecho con listas desoredenadas. Lo podeis ver AQUI.
Meddle, con mucho ojo, me comentó que el problema era que escondia las listas con css, y las enseñaba con javascript (problema), y tendria que hacer esconder las listas a traves del javascript. Lo he estado mirando pero ni papa de cómo hacerlo.
CPB, la tuya funciona de esta manera? sabeis algun tutorial, ejemplo etc,..., de dónde poder mirar??????
cbp
de la mía paso de decir nada, que es una full :P
la mía muestra y esconde usando javascript, pero échale un ojo a la que dicen ellos que seguramente vaya mejor.
marcus
joder...te han tocado el alma :D
Ahora me miro la que dicen....es que me comento esto meddle,.., y me quedé estancado....y no he seguido......
blasco
cbp
de la mía paso de decir nada, que es una full :P
Pero... ¿usted que se esperaba?
Mediocre hasta programando, como no podía ser de otro modo.
:D
marcus
eso, blasco...hecha leña al fuego....
:D
marcus
el menu despegable que ha puesto zigotica, es el de Dave Lindquist (http://www.gazingus.org), que adapté yo, y es el que tiene el problema este, de esconder con css y enseñar con Javascript....
zigotica
marcus
el menu despegable que ha puesto zigotica, es el de Dave Lindquist (http://www.gazingus.org), que adapté yo, y es el que tiene el problema este, de esconder con css y enseñar con Javascript....
el menu desplegable que ha puesto zigotica es de Stuart Langridge y no esconde nada con CSS ;)
marcus
si zigotica,..., has puesto el link, y en este, el Stuart, te pone el suyo (todo javascript) el que digo yo (mitad, mitad) y uno todo css....no? (a ver si que me pierdo algo por el camino...;-) )
XrV
a titulo personal, prefiero hacerlo todo a base de javascript y si no tiene js que se vea desplegado y listos.
zigotica
exacto, o todo js o todo CSS. en este caso prefiero todo js
XrV
bueno, no me gusta ser un bocazas y dar mi opinión sobre las cosas sin ton ni son, lo encuentro un poco hipocrita :P así que vamos a mejorar un poco el script de cbp (la verdad es que lo he escrito desde 0 pero weno :P)
funciona en mozilla 0.9 u IE6. (y navegadores DOM compatibles, así ahorramos parrafada :P)
<code>
<html>
<head>
<style type="text/css">
.menu{
font-family:tahoma;
font-size:11px;
}
</style>
<script type="text/javascript">
window.onload=function(){
var uls = document.getElementsByTagName("ul");
for(var x in uls){
var menu=uls[x];
if(menu.className=="menu"){
//oculta TODOS los UL de dentro de menu
var ocul=menu.getElementsByTagName("ul");
for(var y=ocul.length-1;y>=0;y--){
//definimos un atajo al elemento
e=ocul[y];
//ocultamos el elemento
e.style.display="none";
//sacamos el texto del padre
var labelHijo=e.parentNode.firstChild.nodeValue;
//y eliminamos el nodo que contiene el texto
e.parentNode.removeChild(e.parentNode.firstChild);
//creamos un elemento A (link)
var nuevoLink=document.createElement("A");
//creamos un nodo de texto con el texto del padre
var eltxt=document.createTextNode(labelHijo);
//metemos el texto del padre en el nuevo nodo (link)
nuevoLink.appendChild(eltxt);
//le metemos un estilo (para el cursor) (detallitos que se tienen que pulir)
nuevoLink.style.cursor="pointer";
//creamos un manejador de eventos para mostrar u ocultar el contenido del actual elemento
nuevoLink.onmousedown=function(){
//sacamos el estado del elemento (si es visible o no)
estado=this.parentNode.childNodes[1].style.display;
//so el estado es "no visible"
if(estado=="none"){
//lo mostramos
this.parentNode.childNodes[1].style.display="block";
}else{
//de lo contrario, lo ocultamos
this.parentNode.childNodes[1].style.display="none";
}//fin IF
}//fin evento
//insertamos el nodo este nuevo antes del elemento UL
e.parentNode.insertBefore(nuevoLink,e.parentNode.firstChild)
}//fin del for
}//fin del if
}//fin del for
}//fin del window.onload
</script>
</head>
<body>
<ul class="menu">
<li><a href="#">sin hijos</a></li>
<li><a href="#">sin hijos</a></li>
<li>Con hijos
<ul>
<li><a href="#">hijo</a></li>
<li><a href="#">hijo</a></li>
<li><a href="#">hijo</a></li>
</ul>
</li>
<li><a href="#">sin hijos</a></li>
<li>con nietos
<ul>
<li><a href="#">hijo sin hijos</a></li>
<li>hijo con hijos
<ul>
<li><a href="#">nieto</a></li>
<li><a href="#">nieto</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
</code>
bueno, pues espero mejoras y criticas al script :P
saludines y buenas noches, me voy para la cama que hoy ha sido un dia mu joío ... (dormir toda la noche que uno mismo vomita no es muy agradable, y luego todo el dia con dolor de barriga intenso tampoco mola)
zigotica
bastante mas mejor, sin duda :)
cbp
zigotica quiere más a Xr-V... :( :cry:
voy a echarle un vistazo, a ver si tu script es tan bueno como decís... :P
XrV
ajajaja :P no hombre, no es que me quiera más. lo que pasa es que si a zigotica le metes un menú desplegable no intrusivo gana puntos respecto a uno que está a full de code :P.
la verdad es que nunca me habia pensado que montar un menu de arbol desplegable me llevaria tan poco tiempo, es una pasada la idea del menú con listas :D
cbp
sí sí claro, eso decís todos los niños mimados :P :D
zigotica
bueno, criticas fuertes no tengo marc, pero ahi van un par de detalles:
1. el script no está encapsulado, tus funciones pueden sobreescribir otras funciones del usuario. en este caso lo mejor es unar un literal.
2. el evento onload usado de ese modo no es seguro, puedes sobreescribir otros onload.
3. parseas reiteradamente los mismos UL. primero los recoges todos. luego pasas uno a uno. en cada uno vuelves recoger UL's ... etc etc. No se a bote pronto como hacerlo mas corto y mas eficiente a la vez, pero de entrada creo que es mejor si inicias el script accediendo al menu por id. ahi ya te evitas un paso.
4. añadir imagenes de abrir/cerrar hijos.
y ya que tirar la piedra no me mola, ahi va el pequeño arreglito a partir del codigo de marc (aun faltaria por depurar el tema de la recursion de UL's):
<code><html>
<head>
<style type="text/css">
#menu{
font-family:tahoma;
font-size:11px;
}
</style>
<script type="text/javascript">
var LISTERINE = {
addLoadEvent : function (fn){
var old = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
}
else {
window.onload = function() {
old();
fn();
}
}
},
starter : function(id){
var menu = document.getElementById(id);
//recoge TODOS los UL de dentro de menu
var innul=menu.getElementsByTagName("ul");
for(var y=0; y<innul.length; y++){
//definimos un atajo al elemento
e=innul[y];
//cambiamos estilo al padre:
e.parentNode.style.listStyleType="none";
//ocultamos el elemento
e.style.display="none";
//sacamos el texto del padre
var labelHijo=e.parentNode.firstChild.nodeValue;
//y eliminamos el nodo que contiene el texto
e.parentNode.removeChild(e.parentNode.firstChild);
//creamos un elemento A (link)
var nuevoLink=document.createElement("a");
//creamos un nodo span para añadir las backgroundImage
var elspan=document.createElement("span");
//creamos un nodo de texto con el texto del padre
var eltxt=document.createTextNode(labelHijo);
//metemos el texto del padre en el nuevo nodo (span)
elspan.appendChild(eltxt);
//metemos el span en el Link
nuevoLink.appendChild(elspan);
//le metemos un estilo (para el cursor) (detallitos que se tienen que pulir)
nuevoLink.style.cursor="pointer";
nuevoLink.style.paddingLeft = "0px";
nuevoLink.style.marginLeft = "-20px";
//le metemos un estilo al span
elspan.style.paddingLeft = "20px";
elspan.style.backgroundImage = "url(plus.gif)";
elspan.style.backgroundPosition = "0px";
elspan.style.backgroundRepeat = "no-repeat";
//creamos un manejador de eventos para mostrar u ocultar el contenido del actual elemento
nuevoLink.onmousedown=function(){
//sacamos el estado del elemento UL HIJO (si es visible o no)
estado=this.parentNode.childNodes[1].style.display;
//si el estado es "no visible"
if(estado=="none"){
//lo mostramos
this.parentNode.childNodes[1].style.display="block";
//cambiamos backgroundImage del span:
this.childNodes[0].style.backgroundImage = "url(minus.gif)";
}else{
//de lo contrario, lo ocultamos
this.parentNode.childNodes[1].style.display="none";
//cambiamos backgroundImage del span:
this.childNodes[0].style.backgroundImage = "url(plus.gif)";
}//fin IF
}//fin evento
//insertamos el nodo este nuevo antes del elemento UL
e.parentNode.insertBefore(nuevoLink,e.parentNode.firstChild)
}//fin del for
}
}
LISTERINE.addLoadEvent(function() {
if (document.getElementById && document.getElementsByTagName && document.createElement) {
LISTERINE.starter("menu");
}
})
</script>
</head>
<body>
<ul id="menu">
<li><a href="1.htm">sin hijos</a></li>
<li><a href="2.htm">sin hijos</a></li>
<li>Con hijos
<ul>
<li><a href="3.htm">hijo</a></li>
<li><a href="4.htm">hijo</a></li>
<li><a href="5.htm">hijo</a></li>
</ul>
</li>
<li><a href="6.htm">sin hijos</a></li>
<li>con nietos
<ul>
<li><a href="7.htm">hijo sin hijos</a></li>
<li>hijo con hijos
<ul>
<li><a href="8.htm">nieto</a></li>
<li><a href="9.htm">nieto</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html> </code>
cbp
tío, le has llamado LISTERINE a una variable...
:?
XrV
<code>1. el script no está encapsulado, tus funciones pueden sobreescribir otras funciones del usuario. en este caso lo mejor es unar un literal.</code>
toda la razón, tu mejora le da muchissimo nivel
<code>2. el evento onload usado de ese modo no es seguro, puedes sobreescribir otros onload.</code>
completamente deacuerdo, se me pasó por alto.
<code>3. parseas reiteradamente los mismos UL. primero los recoges todos. luego pasas uno a uno. en cada uno vuelves recoger UL's ... etc etc. No se a bote pronto como hacerlo mas corto y mas eficiente a la vez, pero de entrada creo que es mejor si inicias el script accediendo al menu por id. ahi ya te evitas un paso.</code>
La idea es poder tener multiples menúes de arbol en la misma página simplemente definiendo la clase menú .
a eso viene el " if(menu.className=="menu"){ "
<code>4. añadir imagenes de abrir/cerrar hijos. </code>
jejeje... demasiado tarde era ya para meterme en ese berenjenal
zigotica
soy gracioso, eh? esperaba q alguien viese mi gran sentido del humor, soy tan bueno haciendo chistes que tnego q amargar a los demas tb :)
zigotica
XrV
<code>3. parseas reiteradamente los mismos UL. primero los recoges todos. luego pasas uno a uno. en cada uno vuelves recoger UL's ... etc etc. No se a bote pronto como hacerlo mas corto y mas eficiente a la vez, pero de entrada creo que es mejor si inicias el script accediendo al menu por id. ahi ya te evitas un paso.</code>
La idea es poder tener multiples menúes de arbol en la misma página simplemente definiendo la clase menú .
a eso viene el " if(menu.className=="menu"){ "
hombre ya, el tema es que añade un parseo innecesario, porque ese getbytags(ul) anterior ya recoge todos los UL posteriores! por eso creo que era mejor saltarse ese paso. pero habria q encontrar un metodo mas eficiente y mas corto.
XrV
zigotica
soy gracioso, eh? esperaba q alguien viese mi gran sentido del humor, soy tan bueno haciendo chistes que tnego q amargar a los demas tb :)
he estado buscando por todo el post y no veo el chiste (joajoajoa... esta si que es buena XD)
por lo otro, si, sería cuestión de mirarlo más a fondo :)
zigotica
me referia a lo de LISTERINE, da pena ;)