Cambiar el elemento del menú activo en el desplazamiento de la página usando jQuery

27

Este tutorial le enseñará cómo cambiar el elemento de menú activo en el desplazamiento de la página sin usar ningún complemento o archivo js especial.

En esta demostración, usaremos funciones simples de jQuery para lograr nuestro objetivo.

Rendimiento esperado:

En el evento de desplazamiento de página, el elemento de menú seleccionado (activo) cambiará de acuerdo con la sección actual que se está viendo. También sucederá si el usuario hace clic en cualquiera de los enlaces del elemento del menú. Este tipo de implementación es bueno para sitios web de una sola página que tienen una barra de menú fija. Empecemos.

Demo en vivo

Primer paso: crear el marcado

El marcado es muy simple y fácil. Vamos a crear una barra de navegación simple con pocos elementos de menú como la que tenemos en www.instantshift.com. Tiene pocos elementos como Inicio, Diseño web, CSS, Herramientas, Tutoriales, etc. La página tendrá varios bloques de contenido de texto. Así es como se ve el Marcado.

<div id="maindiv">
    <div class="container clear">
        <div id="sidebar">
            <div id="checkdiv"></div>
            <nav class="">
                <ul>
                    <li><a href="#home" class="active">Home</a></li>
                    <li><a href="#webdesign">Web Design</a></li>
                    <li><a href="#css">CSS</a></li>
                    <li><a href="#tools">Tools</a></li>
                    <li><a href="#tutorials">Tutorials</a></li>
                </ul>
            </nav>
        </div> <!-- sidebar div end -->
        <div id="content">
            <section id="home">
                <h1>Home</h1>
                <p><!-- Home Content Goes Here --></p>
            </section>
            <section id="webdesign">
                <h1>Web Design</h1>
                <p><!-- Web Design Content Goes Here --></p>
            </section>
            <section id="css">
                <h1>CSS</h1>
                <p><!-- CSS Content Goes Here --></p>
            </section>
            <section id="tools">
                <h1>Tools</h1>
                <p><!-- Tools Content Goes Here --> </p>
            </section>
            <section id="tutorials">
                <h1>Tutorials</h1>
                <p><!-- Tutorials Content Goes Here --></p>
            </section>
        </div> <!-- contain div end -->
    </div> <!-- container div end -->
</div><!-- maindiv end -->

Nuestro marcado Html está listo, ahora es el momento de agregar un poco de estilo CSS.

Paso dos: agregar clases CSS.

body{
      background-color:#520000;font-size:17px;
}
 
#maindiv{
      background:#F4F3E8 url(images/page_bg.webp);
}
 
#title h1 {
     text-align: right;font-weight: bold;font-size: 25px;margin: 0;color:#fff;
}
 
.container {
     width: 1000px;margin: 0 auto;padding: 38px 0;
}
 
#wrapper{
     margin:0px auto;
}
 
#sidebar {
    width:250px;float:left;
}
 
#content {
   width:720px;float:right;padding-left:12px;
}
 
#title {
   width: 900px;height: 60px;float: right;
}
 
.clear:after {
   visibility: hidden;display: block;content: "";clear: both;height: 0;
}
 
nav {
  width:213px;background-color:#030000;border: 2px solid #4F4D4D;padding:0 12px;
}
 
nav.stickydiv {
   position: fixed;top: 0;z-index: 10000;margin-top:12px;
}
 
nav ul {
list-style-type:none;margin:0;padding:0;
}
 
nav li {
padding:5px 10px;
}
 
nav li a {
color:#fff;font-weight:700;line-height: 25px;
}
 
a{
text-decoration:none;
}
 
.active {
color: #F99;text-decoration: none;
}
 
p{
font-family:Verdana,Arial,Helvetica,sans-serif;
}
 
footer p{
  color:#fff;
}

Paso tres: Comprobación del área de juegos "jQuery".

En primer lugar, nos aseguramos de que al hacer clic en los enlaces del menú, el div correspondiente se desplace hacia arriba. Como puede ver en el código a continuación, al hacer clic en el enlace del elemento del menú, estamos eliminando la clase "activa" del elemento del menú seleccionado actualmente y agregando la clase activa al enlace del elemento en el que se hizo clic.

Entonces estamos obteniendo la ID del elemento en el que se hizo clic. this.hash devolverá "#foo", que es el selector de ID. Por lo tanto, $(this.hash) es lo mismo que $(“#foo") y seleccionará el elemento con ID foo.

$('a[href^="#"]').on('click', function (e) {
        e.preventDefault();
        $(document).off("scroll");
         
        $('a').each(function() {
            $(this).removeClass('active');
        })
        $(this).addClass('active');
         var target = this.hash,
         menu = target;
        $target = $(target);
               
       $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 600, 'swing', function() {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });

En el evento de desplazamiento, comprobamos la posición de los elementos frente a la cantidad de desplazamiento, así como la suma de su altura y posición. Sobre esta base, estamos agregando y eliminando la clase activa de los elementos del menú.

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#sidebar a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#sidebar ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}

y por último, en el evento de desplazamiento de la página, estamos comprobando si la barra lateral estará pegajosa o no.

$(window).scroll(function(){
        // the "12" should equal the margin-top value for nav.stickydiv
        var window_top = $(window).scrollTop() + 12;
        var div_top = $('#checkdiv').offset().top;
            if (window_top >= div_top) {
                $('nav').addClass('stickydiv');
            } else {
                $('nav').removeClass('stickydiv');
            }
 });

Aquí está el guión completo.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(window).scroll(function(){
        var window_top = $(window).scrollTop() + 12;
       // the "12" should equal the margin-top value for nav.stickydiv
        var div_top = $('#checkdiv').offset().top;
        if (window_top >= div_top) {
                $('nav').addClass('stickydiv');
            } else {
                $('nav').removeClass('stickydiv');
            }
    }); 
 
  $(document).on("scroll", onScroll);
 
$('a[href^="#"]').on('click', function (e) {
      e.preventDefault();
        $(document).off("scroll");
         $('a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');
         var target = this.hash,
         menu = target;
         $target = $(target);
       $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 600, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });
});
 
function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#sidebar a').each(function () {
        var currLink = $(this);
       var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#sidebar ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
}
</script>

Eso es todo, es fácil ¿verdad? ¡Disfrutar! No te olvides de ver la demostración.

Demostración en vivo y código fuente

Aquí puedes ver este menú de acción en acción en vivo. Además, puede descargar los archivos fuente para que pueda editarlos y usarlos directamente en lo que quiera.

Demostración en vivo  Descargar código fuente

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More