Foros del Web » Programando para Internet » Jquery »

Menu autoselectivo en desplazamiento vertical

Estas en el tema de Menu autoselectivo en desplazamiento vertical en el foro de Jquery en Foros del Web. Hola a todos, he visto que algunas webs recrean un menu que sigue el desplazamiento vertical de una pagina web dividida en varias zonas, según ...
  #1 (permalink)  
Antiguo 19/09/2014, 09:12
 
Fecha de Ingreso: enero-2008
Mensajes: 581
Antigüedad: 16 años, 10 meses
Puntos: 9
Menu autoselectivo en desplazamiento vertical

Hola a todos, he visto que algunas webs recrean un menu que sigue el desplazamiento vertical de una pagina web dividida en varias zonas, según la zona donde se este se marca una zona u otra del menu, ¿Es posible hacerlo de forma sencilla con jQuery?

Ejemplo1


Ejemplo2

gracias
  #2 (permalink)  
Antiguo 19/09/2014, 15:20
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Menu autoselectivo en desplazamiento vertical

Puedes hacerlo incluso sin necesidad de echar mano de una librería. Este es un ejemplo que hice:

Código HTML:
Ver original
  1. <nav>
  2.     <li>Zona 1</li>
  3.     <li>Zona 2</li>
  4.     <li>Zona 3</li>
  5. </nav>
  6. <div>Zona 1</div>
  7. <div>Zona 2</div>
  8. <div>Zona 3</div>

Código CSS:
Ver original
  1. div{
  2.     height: 800px;
  3. }
  4.  
  5. nav{
  6.     background: lightsteelblue;
  7.     position: fixed;
  8.     width: 100%;
  9.     top: 0;
  10. }
  11.  
  12. nav li:hover, nav li:first-child{
  13.     background: steelblue;
  14. }

Código Javascript:
Ver original
  1. var divs = document.querySelectorAll("div"),
  2.     opts = document.querySelectorAll("nav li"),
  3.     totDivs = divs.length,
  4.     totOpts = opts.length,
  5.     fn = function(j){
  6.         for (var i = 0; i < totOpts; i++){
  7.             opts[i].style.background = i == j ? "steelblue" : "lightsteelblue";
  8.         }
  9.     };
  10.  
  11. window.addEventListener("scroll", function(e){
  12.     for (var i = 0; i < totDivs; i++){
  13.         if (this.scrollY > (divs[i].offsetTop - document.documentElement.clientHeight)){
  14.             fn(i);
  15.         }
  16.     }
  17. }, false);

Esto es sencillo. Tengo un menú con tres opciones y, abajo de este, tres divisiones. Dichas divisiones tienen una altura de 800 píxeles, mientras que coloreo a la primera opción del menú, para que, cuando cargue la página, dicha opción se encuentre marcada por defecto. En el código JS, obtengo al conjunto de divisiones y opciones del menú, obtengo el total de elementos que poseen y declaro una función que usaré más adelante. Cuando se haga scroll en la ventana (desplazamiento con la barra), recorro al conjunto de divisiones existentes. En cada iteración, realizo la siguiente condición: Si la cantidad de píxeles desplazados al hacer scroll es mayor que la resta de la distancia que hay entre la división actual en la iteración con respecto al elemento que lo contiene menos la altura del elemento raíz del documento (<html>), quiere decir que dicha división ya es visible y, por lo tanto, procedemos a ejecutar la función que declaramos al inicio, enviándole como parámetro el número de división equivalente en el bucle.

En la función, recorremos al conjunto de opciones del menú y, en cada iteración, iremos asignando un color de fondo a las opciones. Si el contador de dicho bucle es igual al valor recibido, querrá decir que el número de opción es equivalente al número de división que se está mostrando, por lo que le asigno el mismo color que asigné por defecto a la primera opción, caso contrario, le asigno el color de fondo del menú.

Para que no tengas problemas de compatibilidad con navegadores antiguos, básicamente las versiones anteriores a IE9, te sugiero leer la documentación de los métodos que he utilizado en este ejemplo:

DEMO

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #3 (permalink)  
Antiguo 19/09/2014, 19:35
 
Fecha de Ingreso: enero-2008
Mensajes: 581
Antigüedad: 16 años, 10 meses
Puntos: 9
Respuesta: Menu autoselectivo en desplazamiento vertical

Genial!! me gusda

Pero da el salto nada mas rebasar el final del navegador, en lugar de al principio ejemplo

y para agregarle enlaces supongo que lo normal es usar:
Código:
<a href="#uno"
Código:
<section id="uno">
  #4 (permalink)  
Antiguo 19/09/2014, 19:40
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Menu autoselectivo en desplazamiento vertical

En realidad, el cambio se produce cuando la división es visible al momento de hacer scroll. Recuerda que la condición hace que precisamente se controle eso. Prueba haciendo más altas a las divisiones para que lo compruebes.

Con respecto a lo otro (las anclas o almohadillas), no lo había añadido porque no era el fin del ejemplo, pero sí, es lo que deberías de usar, aunque también podrías hacerlo sin ellas, pero usándolas, se te hará todo más fácil.

Saludos

Edito: Creo que ya sé a qué te referías. Quieres que el cambio se de cuando la parte superiore de la sección o división quede encuadrada en la parte superior de la ventana. Bastaría con que, a la resta que hay en la condición, le sumes la altura interna de la ventana (sin la barra de direcciones, de favoritos, etc., solo el contenido) menos la altura del menú. El código quedaría así:

Código Javascript:
Ver original
  1. var divs = document.querySelectorAll("div"),
  2.     opts = document.querySelectorAll("nav li"),
  3.     nav = document.querySelector("nav"),
  4.     heightNav = parseInt(window.getComputedStyle(nav, null).height),
  5.     totDivs = divs.length,
  6.     totOpts = opts.length,
  7.     fn = function(j){
  8.         for (var i = 0; i < totOpts; i++){
  9.             opts[i].style.background = i == j ? "steelblue" : "lightsteelblue";
  10.         }
  11.     };
  12.  
  13. window.addEventListener("scroll", function(e){
  14.     for (var i = 0; i < totDivs; i++){
  15.         if (this.scrollY > (divs[i].offsetTop - document.documentElement.clientHeight) + (this.innerHeight - heightNav)){
  16.             fn(i);
  17.         }
  18.     }
  19. }, false);

DEMO

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 19/09/2014 a las 20:09 Razón: Actualización
  #5 (permalink)  
Antiguo 20/09/2014, 16:54
 
Fecha de Ingreso: enero-2008
Mensajes: 581
Antigüedad: 16 años, 10 meses
Puntos: 9
Respuesta: Menu autoselectivo en desplazamiento vertical

Has dado en el clavo, a eso me referia, creo que es la forma mas común que vienen en algunas web, otras sin embargo hacen la división al revasar el 50% del height del navegador

gracias

Cita:
Edito: Creo que ya sé a qué te referías. Quieres que el cambio se de cuando la parte superiore de la sección o división quede encuadrada en la parte superior de la ventana. Bastaría con que, a la resta que hay en la condición, le sumes la altura interna de la ventana (sin la barra de direcciones, de favoritos, etc., solo el contenido) menos la altura del menú. El código quedaría así:
Uso bootstrap que usa <li class="active"> voy a intentar adaptar la siguiente linea buscando ejemplos, aunque solo con js parece complicado comprobar y cambiar un class, veo que cambiar un id es mas facil
Código:
opts[i].style.background = i == j ? "steelblue" : "lightsteelblue";
Buscando me aproximo a esto... voy a probar (aunque me gusta mas tu linea que parece un if)
Código:
if (opts[i].className == "active") {opts[i].className=""}else{opts[i].className="active"}
Quizas... Noto con esta linea que siempre pinta clase=...
Código:
opts[i].className = i == j ? "active" : "";

Última edición por quico5; 20/09/2014 a las 17:32
  #6 (permalink)  
Antiguo 20/09/2014, 23:31
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Menu autoselectivo en desplazamiento vertical

Cita:
Iniciado por quico5 Ver Mensaje
Uso bootstrap que usa <li class="active"> voy a intentar adaptar la siguiente linea buscando ejemplos, aunque solo con js parece complicado comprobar y cambiar un class, veo que cambiar un id es mas facil
Código:
opts[i].style.background = i == j ? "steelblue" : "lightsteelblue";
Cita:
Iniciado por quico5 Ver Mensaje
Buscando me aproximo a esto... voy a probar (aunque me gusta mas tu linea que parece un if)
Código:
if (opts[i].className == "active") {opts[i].className=""}else{opts[i].className="active"}
Para cambiar la clase, solo necesitas trabajar con la propiedad className, como veo que ya lo hiciste. En mi ejemplo, uso operadores ternarios, que se utilizan para realizar condiciones. Lo que va a la izquierda del signo de interrogación, es la condición. Lo que está a la derecha del signo de interrogación y a la izquierda de los dos puntos, es la instrucción a ejecutar cuando la condición se cumpla y lo que está a la derecha de los dos puntos, es la instrucción a ejecutar cuando la condición no se cumpla.

Cita:
Iniciado por quico5 Ver Mensaje
Quizas... Noto con esta linea que siempre pinta clase=...
Código:
opts[i].className = i == j ? "active" : "";
A eso me refería.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Etiquetas: desplazamiento, vertical
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:22.