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

[linux] file_get_contents de PHP no puede acceder a otro servidor de la misma LAN

Acabo de escribir sobre nuestros devaneos neuronales para lograr hacer funcionar los enlaces permanentes de Wordpress en un servidor remoto RedHat . Y ahí mencioné que antes de dicho problema, habíamos tenido que luchar con otro igual de porfiado y jaquecoso. La situación era esta: Tenía un script que solicitaba información a un servidor remoto. Valiéndome de file_get_contents() , en mi instalación de localhost lograba conectar con el servidor remoto, pues estábamos en la misma LAN, o red local. Pero, claro, mi servidor local es un Windows 10 con Xampp, que prácticamente no tiene inhibiciones ^^U Por lo que la comunicación era directa y sin tapujos. Pero cuando subí mi sitio web al servidor de desarrollo, al que llamaré "Servidor A", la cosa ya no funcionó tan bonita. Pues, aun estando en la misma LAN, el servidor remoto, que llamaré "Servidor B", no contestaba las solicitudes del nuevo chico del barrio, "Servidor A".  No profundizaré en todos los caminos...

[google.maps] Restringir polígono dentro de otro

Hola a todos!! En mi trabajo me toca desarrollar hartas cosas bonitas usando la API de Google Maps . La última cosa bonita que estoy haciendo es un Editor Gráfico web, que ocupa Polyline s y Rectangle s. En el siguiente registro les quiero dejar algunos tips sobre cómo lograr cierta característica que puede serles útil, aun si su desarrollo no apunta a lo mismo. Por lo mismo, este tip requiere de conocimientos previos de manejo de la API para comprenderlo. Vamos al asunto. El Editor que estoy realizando requiere de un área base, o como diríamos en términos gráficos, un lienzo donde trabajar. El objetivo es que el usuario sólo trabaje dentro de esta área, y no fuera de ella. Para ello, me valgo de algunas configuraciones previas, que incluyen un par de variables globales, y algunos manejadores de eventos de Google Maps. Una variable global me indica en qué "Modo" se encuentra el usuario: para este caso, los valores pueden ser "creando" o "en espera". Otra...

[linux] Error 404 al usar reglas de .htaccess en Apache

Hola a tod@s. Los últimos días estuvimos luchando con mi compañero de pega, intentando averiguar por qué los enlaces bonitos de Wordpress no funcionaban en el nuevo servidor RedHat que mi amigo levantó para el efecto. Les cuento la historia desde el principio.  Hice una instalación de Wordpress 6.2.2 en mi servidor local (mi pc con Xampp) para poder desarrollar un Theme acorde al requerimiento que me habían dado de hacer una web con x características. Todo bien ahí. Los problemas comenzaron cuando repliqué mi desarrollo en el servidor remoto. No hablaré del primer problema que tuvimos, porque no viene a cuento en el actual tema . Tal vez otro día escriba sobre eso . Pero sí decir que nos tomó tiempo solucionarlo, y cuando por fin lo logramos, y veíamos todo color de rosa, apareció este otro desgraciado a matarnos la felicidad: los enlaces formateados que nos ofrece Wordpress no funcionaban en el servidor remoto. El camino para darle explicación y solución daba comienzo: Revisión d...