Tengo el siguiente .js que contiene las diferentes clases y funciones que definen y construyen el meú:
Código HTML:
/****************************************************************************** Fecha: 10/7/2002 Código original de la web Javascriptdesdecero ******************************************************************************/ /*===================================================================================== Todos los comentarios que siguen sólo tienen como misión explicar el funcionamiento de esta aplicación, por lo que puedes borrarlo para aligerar el archivo. ======================================================================================*/ /************************************************************************************** NOMBRE: estilosDefecto() ARGS: ninguno RETURN: nada DESCR: Esta función se usa para crear estilos por defecto para presentar el menú en caso de que el usuario no defina estilos propios. Puedes modificarla si quieres usar otros estilos por defecto. ***************************************************************************************/ function estilosDefecto() { var ult = document.styleSheets.length; var nhoja, vns, i if (document.all) { nhoja = document.createStyleSheet(null, ult); nhoja.addRule('.menux', "background-color : Menu; font : menu;line-height : 150%; width : 100px; position : absolute; border : thin outset"); nhoja.addRule('.itemonx',"color: Black; cursor: hand;width: 100%") nhoja.addRule('.itemoffx',"color: HighlightText;background-color: ActiveCaption; cursor: hand; width: 100%;") nhoja.addRule('.separador', "border-bottom-style : groove; border-bottom-width : thin;background-color : transparent; height: 2px;width: 100%"); } else { nhoja = document.styleSheets.item(0) nhoja.insertRule('.menux {background-color : Menu; font : menu;line-height : 150%; width : 100px; position : absolute; border : thin outset}',0); nhoja.insertRule('.itemonx {color: Black; cursor: pointer;width: 100px}',0) nhoja.insertRule('.itemoffx {color: HighlightText;background-color: ActiveCaption; cursor: pointer; width: 100px;}',0) nhoja.insertRule('.separador {border-bottom-style : groove; border-bottom-width : thin;background-color : transparent; height: 2px;width: 100px}',0); } } /************************************************************************************** NOMBRE: oItemFlot(texto, enlace, target, estilo1, estilo2) ARGS: texto: cadena con el nombre de la opción enlace: dirección del hipervínculo correspondiente a la opción target: donde se abrirá la nueva página. Una cadena vacía indica la misma página Puede ser el nombre de un frame. estilo1: estilo de los items no activos estilo2: estilo de los items activos (cuando el ratón pasa por encima) RETURN: nada DESCR: Este es el objeto oItemFlot usado para construir las opciones del menu. Propiedades: ventana: ventana donde se abrirá la nueva página objHTML: es el objeto SPAN donde se aloja el item. Para este objeto se describen las siguientes propiedades y métodos: cambPagina: Realiza el cambio de página al pulsar una opción del menú enlace: dirección de la nueva página target: donde se abrirá la nueva página ***************************************************************************************/ function oItemFlot(texto, enlace, target, estilo1, estilo2) { this.objHTML = document.createElement('DIV'); this.objHTML.cambPagina = cambPagina; this.objHTML.enlace = enlace; this.objHTML.target = target; this.objHTML.ventana = null; if (!estilo2) estilo2='itemoffx' if (!estilo1) estilo1='itemonx' //Escribe el texto de la opción y coloca los eventos de ratón this.objHTML.className = estilo1; if (texto != "") { this.objHTML.innerHTML = " "+texto; this.objHTML.onmouseover= new Function("this.className='"+estilo2+"'") this.objHTML.onmouseout= new Function("this.className='"+estilo1+"'") this.objHTML.onmousedown = this.objHTML.cambPagina } if (target!='' || target !=null) for(var i=0; i< window.frames.length; i++) { if (window.frame.name == target) this.ventana = window.frame; } function cambPagina() { if (this.target!="") { if (!this.ventana || this.ventana.closed) { this.ventana = window.open(this.enlace, target) } else{ this.ventana.location.href = this.enlace; this.ventana.focus(); } } else window.location.href = this.enlace; } } /************************************************************************************** NOMBRE: oMenuFlot(id, estilo, opcnorm, opcact) ARGS: id: identificador HTML para el bloque que contendrá al menú estilo: (string) nombre de la clase del bloque que contendrá el menú opcnorm: (string) nombre de la clase para los items no seleccionados opcact: (string) nombre de la clase para los items activos (con el ratón encima) RETURN: nada DESCR: Este es el objeto oMenuFlot, el que al pulsar el ratón derecho del ratón aparece en la posición de éste en la página. Métodos: nuevoItem: añade un nuevo item al menú separador: añade un separador entre opciones menuDer: función llamada al pulsar el botón dereco del ratón menuActivar: función que asigna eventos y activa el menú flotante Propiedades: opcnorm: (string) estilo de los items no seleccionados opcact: (string) estilo de los items seleccionados (con el ratón encima) menuHTML: objeto correspondiente al bloque DIV que se usará para dibujar el mnú en la ventana. ***************************************************************************************/ function oMenuFlot(id, estilo, opcnorm, opcact) { //Métodos this.nuevoItem = nuevoItem; this.separador = separador; this.menuDer = menuDer this.menuActivar = activar; //Propiedades this.opcnorm = opcnorm; this.opcact = opcact; this.menuHTML = document.createElement("DIV"); this.menuHTML.className = estilo||'menux'; this.menuHTML.id = id this.menuHTML.style.visibility="hidden" document.body.appendChild(this.menuHTML) //Si no se indica el estilo del menú usa los estilos por defecto if (!estilo) estilosDefecto(); function nuevoItem(texto, enlace, target) { var opc = new oItemFlot(texto, enlace, target, this.opcnorm, this.opcact) var br = document.createElement("BR"); this.menuHTML.appendChild(opc.objHTML); //this.menuHTML.appendChild(br); } function separador(estsep) { var sep = document.createElement('HR') sep.className = estsep||'separador' this.menuHTML.appendChild(sep); } function menuDer(ev) { with(this.menuHTML){ if (!document.all) { event=ev; style.left= event.pageX style.top = event.pageY } else { style.top = event.clientY+document.body.scrollTop; style.left = event.clientX+document.body.scrollLeft; } if (event.button & 2) style.visibility="visible" else style.visibility="hidden" } return false; } function activar(omenu) { document.oncontextmenu = new Function('return false'); document.onmousedown = new Function("event", omenu+".menuDer(event)") //document.onmouseout = new Function('return false'); } } /*------------------FIN DEL CÓDIGO PARA EL MENU FLOTANTE -------------------*/
Código HTML:
<SCRIPT language=JavaScript type=text/JavaScript> function preparar(titulo,url,modo) { //Se define la variable, global, para el menú. Al constructor del objeto se le pasan //como argumentos: //cadena con el identificador que quiera susarse para el menú //cadena con el nombre de la clase o estilo del menú //cadena con el nombre de la clase o estilo de las opciones no activas //cadena con el nombre de la clase o estilo de las opciones activas //Si falta alguno de los nombres de estilo se usan los estilos por defecto window.elmenu = new oMenuFlot('elmenu'); //Una vez creado el menú se le añaden las opciones con el método nuevoItem //Los argumentos necesarios son //cadena con el título de la opción //cadena con la dirección URL a la que se pasa al pulsar la opción //cadena con el nombre de la ventana en la que debe abrirse la opción elmenu.nuevoItem(titulo,url,modo) elmenu.separador(); elmenu.nuevoItem('Página # 3', 'pagina_3.htm','blanco') elmenu.menuActivar('elmenu'); } </SCRIPT>
Código HTML:
<table> <tr> <td OnContextMenu="JavaScript:preparar('Página # 1','pagina_1.html','blanco');"></td> <td OnContextMenu="JavaScript:preparar('Página # 2','pagina_2.html','blanco');"></td> </tr> </table>
Esto funciona bien, solo que se crea una instancias del menú por cada click derecho que se da en cualquier celda y estas instancias (menús) no desaparecen.
Me gustaria recibir orientación sobre cómo puedo:
a) Evitar que se cree una instancia del menú por cada click derecho que se da en las celdas. Que siempre sea una sola.
b) Que el meú desaparezca por sí solo después de ciertos segundos de haber aparecido o de un mouseout.
Muchas gracias por su ayuda.