Ir al contenido principal

[javascript] Scroll vertical se vuelve loco al trabajar un menú fijo (fixed menu)

Estoy trabajando en el desarrollo de una página web, en la cual va incluido un menú en la parte superior, de esos amplios que están tan de moda en el diseño gráfico web hoy en día. La idea es que al bajar por la página, este menú permanezca fijo y visible en la parte superior de la página, pero con el detalle de que sea una versión reducida del menú original. O sea, disminuye el alto del menú y el tamaño de la fuente, a fin de no molestar demasiado con el resto del contenido visible en la ventana. 

El problema:

Hasta ahí había logrado hacer toda la funcionalidad usando CSS y Javascript. De hecho iba perfecto, exceeeeepto en algunas ocasiones en las que, especialmente cuando la cantidad de contenido en la página no alcanzaba a traspasar mucho el alto de la ventana, y se generaba la barra de desplazamiento vertical, con la cual yo intentaba bajar con el scroll, el mismo se volvía loco y alternaba la apariencia del menú superior entre la amplia y la reducida, moviendo el scroll por sí mismo de arriba a abajo en un pinponeo visual super molesto. Como quien dice, parecía que la página se estancaba en este vaivén super rápido, y encima no permitía bajar, pues cada vez que bajaba, la página me devolvía a la parte superior de la misma.

La investigación:

Estuve depurando los datos por un rato en la consola de Chrome, y lo único que podía entender era que en algún punto, cuando el evento del scroll vertical superaba la posición que yo le daba para transformar el menú amplio por el reducido, efectivamente realizaba la reducción, pero de inmediato, por sí solo, volvía a moverse hacia arriba, a la posición 30px, por lo que volvía a mostrar el menú amplio, y eso lo repetía unas veinte veces hasta parar. Esos 30px que se repetían me hizo pensar que el problema tenía que ver con las medidas. Por eso entré a modificar mi función, mi algoritmo, incluso redondeé los valores, pero nada, no resultaba.

Investigué, y encontré mi pregunta en el sitio de StackOverflow (Toggling div position:fixed sometimes causes scrolling bug). Si bien había varias respuestas, e incluso una de ellas dada por correcta, todo estaba en inglés, y reconozco que en viernes por la tarde mi cerebro está medio fundido como para traducir bien, jajaja, así que con suerte logré entender la respuesta correcta, y no me convenció su solución (hablaban de crear una DIV que sirviera de referencia para el evento scroll, una DIV que no cambiara de posición, pues siempre iba a estar antes que el menú, por lo que el evento no causaría estragos. Pero esa solución de poner otro DIV antes de los míos no me gustaba.). 

Seguí leyendo las demás respuestas, pero ya en modo lectura rápida, y fue así que en una de ellas creí que entrever que hablaba sobre el "alto del documento". Y ahí me vino el "ting!" jajaja! Lo entendí: lo que estaba pasando era que el documento de mi página era modificado cada vez que yo alternaba entre el menú amplio y el reducido, y por eso el scroll se volvía loco. Ahora lo explico.

El documento de una página web tiene un alto. Esto suena tan obvio que ni siquiera había pensado que esto era así. O sea, siempre manejamos el ancho de nuestra página y de los elementos en ella, e incluso el alto de estos elementos, pero nunca nos preocupamos mucho del alto de la página en sí.

Pues bien, este alto existe, y en este caso, estaba medido en pixels. Pixels que se veían modificados cada vez que yo le cambiaba el alto a mi menú superior.


/* CSS de mi menú amplio (por defecto, al ver la página en su parte superior): */
#menu
{
  height:102px;
}

/* CSS de mi menú reducido (al desplazarnos hacia abajo en la página): */
#menu.reducido
{
  position:fixed;
  top:0;
  height:60px;
}

 

La solución: 

Agregar un <DIV> en el pie de página (generalmente llamado footer), que actuará como regulador del alto de la página. Para este elemento no necesitamos generar estilos (CSS), sólo necesitamos identificarlo.

  <!-- Esto sería el pie de página o Footer -->
  <div id="footer">
   <!-- Aca el contenido de nuestro footer -->
   <div id="ajuste"></div>
  </div>
 </body>
</html>

Luego, en el mismo Javascript donde tenemos nuestra función que realiza la conversión entre el menú amplio y el reducido, agregamos el "ajuste" de alto:

function alternarMenu()
{
  var menu = document.getElementById("menu");
  var ajuste = document.getElementById("ajuste");
  var altoMinimo = 60;

  if (window.scrollY > altoMinimo)
  {
    menu.className = "reducido";
    ajuste.style.height = "42px";
  }
  else if (
window.scrollY < altoMinimo)
  {
    menu.className = "";
    ajuste.style.height = "0";
  }
}
window.addEventListener("scroll", alternarMenu);


Este código, por supuesto, es una super mega simplificación del código real, pero es para que se entienda que en el mismo momento en que le ordenamos al menú cambiar su estilo (o clase), al mismo tiempo debemos alterar el alto del DIV de ajuste, de modo que nuestro alto de documento no varíe. Eso es lo más importante. De ese modo, "engañamos" al scroll, haciéndole creer que nada ha cambiado y que puede proceder como corresponde con nuestro menú cambiante ^_^

Y pues eso. Esa fue la solución que encontré, y que me puso muy contenta, jejeje.
Espero que les sirva también a ustedes.

Gracias por leer, saludos y que tengan buena programación! ^_^

Comentarios

Entradas populares de este blog

[wordpress] Configurar Red Multisitio

 Hola a todos! Después de mucho tiempo, por fin traigo un nuevo tip para desarrolladores principantes (como yo) de WordPress. En esta ocasión, les dejaré los pasos para poder configurar su instalación actual de WordPress como una red de multisitios. Para ello necesitarán tener acceso a los archivos del servidor web (vía FTP o similar), pues tendrán que editar y guardar algunos de ellos. Contexto WordPress nos ofrece una muy buena opción para administrar contenidos de sitios web (CMS, content managment system ). Usualmente, tenemos un sitio web asociado a esta instalación. Pero cuando necesitamos crear un nuevo sitio web, independiente del anterior, pero usando WordPress, lo que solemos hacer es crear una nueva ubicación en el servidor e instalar nuevamente WordPress en esta nueva carpeta.  Esto funciona bien, pero estamos olvidando que WordPress nos permite administrar más de un sitio con la misma instalación. Esta opción no está visible por defecto en la administración del CM...

[phpMyAdmin] El almacenamiento de configuración phpMyAdmin no está completamente configurado...

Estaba trabajando en la página de Wordpress para mi cliente, en mi instalación local ( localhost ) y cuando se me ocurre actualizar un par de plugins de WP, todo se cae. Wordpress me da unos avisos horribles de que el usuario de base de datos de WP no tiene el privilegio para alterar la BD... Me sugiere reparar las tablas. Y cuando voy a phpMyAdmin (pMA), el administrador de la BD, éste me sale con el mensaje: El almacenamiento de configuración phpMyAdmin no está completamente configurado, algunas funcionalidades extendidas fueron deshabilitadas. Averigüe por qué. Le doy click al link de "Averigüe por qué" y me muestra un nuevo mensaje, que me informa que la "Configuración de pma ... no recibió el OK ". El primer mensaje me apareció en la pantalla de inicio de phpMyAdmin.  Pero yo primero lo vi (no exactamente el mismo) en la pestaña de Operaciones de la BD de WP... y sucesivamente en la pestaña de Operaciones de todas las BD. En este caso, me ofrecía crear las ta...

[tip] Leer Código QR sin cámara, desde tu navegador web

Hola a todos. Regularmente estamos encontrándonos con que, tras terminar de leer un anuncio o información, el remitente nos deja un código QR para que podamos expandir nuestro conocimiento respecto del tema recién leído. La lectura de estos códigos se ha vuelto muy popular y accesible a todos los usuarios gracias a los dispositivos móviles. Si el mismo no cuenta con una cámara que tenga incorporado el lector, siempre podemos descargar e instalar una liviana aplicación que cumpla con esta función. Todo bien hasta ahí. Pero, ¿qué pasa si estoy en el computador, sentada frente a la pantalla que me muestra el código, y no me interesa tener que tomar el teléfono móvil, activarlo, abrir la aplicación de lectura de código, enfocar a la pantalla del computador, leer el código, copiar el texto obtenido, buscar la forma de traspasarlo a mi computador (yo generalmente lo envío a un contacto de confianza de Whatsapp, para luego leerlo desde Web Whatsapp -_-), para hacer algo que debiera estar inco...