jQuery addClass in scroll

2

I have the code below and I'm trying to get the li elements to get with the active class depending on scroll (parallax effect ), everything works well (click functions for the scroll) except that. If you know better, please share.

HTML:

<div id="wrapper">

    <nav>
        <ul>
            <li>
                section1
            </li>
            <li>
                section2
            </li>
            <li>
                section3
            </li>
            <li>
                section4
            </li>
        </ul>
    </nav>

    <div id ="section1">
        <p>vccvfcwec</p>
    </div>

    <div id ="section2">
        <p>vccvfcwec</p>
    </div>

    <div id ="section3">
        <p>vccvfcwec</p>
    </div>

    <div id ="section4">
        <p>vccvfcwec</p>
    </div>

</div>

jQuery:

$('ul li:eq(0)').click(function() {
    $('html, body').animate({
        scrollTop: $("#section4").offset().top
    }, 1500);
});
$('ul li:eq(1)').click(function() {
    $('html, body').stop().animate({
        scrollTop: $("#section3").offset().top
    }, 1500);
});
$('ul li:eq(2)').click(function() {
    $('html, body').stop().animate({
        scrollTop: $("#section2").offset().top
    }, 1500);
});
$('ul li:eq(3)').click(function() {
    $('html, body').stop().animate({
        scrollTop: $("#section1").offset().top
    }, 1500);
});

var section1Height = $('#section1').height();
var section2Height = $('#section2').height();
var section3Height = $('#section3').height();
var section4Height = $('#section4').height();

$(window).scroll(function() {
    var winTop = $(window).scrollTop();

    if(winTop > section1Height && winTop <= section2Height){
        $('ul li:eq(0)').addClass('active').not().removeClass('active');
    }
    else if(winTop > section2Height && winTop <= section3Height){
        $('ul li:eq(1)').addClass('active').not().removeClass('active');
    } 
    else if(winTop > section3Height && winTop <= section4Height){
        $('ul li:eq(2)').addClass('active').not().removeClass('active');
    }
    else if(winTop > section4Height){
        $('ul li:eq(3)').addClass('active').not().removeClass('active');
    }
});

CSS:

    .active {
    color:#fff !important;
}

#wrapper {
    width: 100%;
    max-width: 1024px;
    margin: 0 auto;
}
#section1{
    width: 100%;
    height: 2000px;
    position: relative;
    background-color: yellow;
}
#section2 {
    width: 100%;
    position: relative;
    height: 2500px;
    background-color:red;
}
#section3{
    width: 100%;
    position: relative;
    height: 1500px;
    background-color: green;
}
#section4{
    width: 100%;
    position: relative;
    height: 1500px;
    background-color: blue;
}
nav ul {
    border: 1px solid;
    margin: 0;
    background-color: #222;
    height: 80px;
    margin: 0 0 90px;
    width: 100%;
    max-width: 1024px;
    position: fixed;
    z-index: 1;
}
nav ul li {
    list-style: none;
    margin: 30px 20px 30px 20px;
    display: inline;
    cursor: pointer;
    float: right;
}
nav ul li {
    color: #B5B5B5;
    text-decoration: none;
}
    
asked by anonymous 09.04.2014 / 18:21

1 answer

1

If I understood your problem well, each section should have your text in yellow when the scroller arrives, ie when that section is +/- in the middle of the screen. Here is an example that works on jsFiddle but has to be adapted to your code that is incomplete here in the question.

My idea is:

  • Cache all sections whose ID starts with and and sections that are descendants of #wrapper
  • go through this choice and save several objects with their height and a reference to the object itself.
  • within for go through all elements. The first one that has posicao greater than wintop makes the cycle stop and fetches the corresponding li to give it a class

Code

function animarScroll(altura) {
    $('html, body').stop().animate({
        scrollTop: altura
    }, 1500);
}

var ecra = $(document).height();
var seccoes = $('#wrapper div[id^=section]');
var lis = document.querySelectorAll('#wrapper li');
var alturas = seccoes.map(function (i) {
    return {
        elemento: lis[i],
        posicao: $(this).position().top + $(this).outerHeight(true)
    }
});

$('ul li').each(function (i, el) {

    $(el).click(function () {
        var posicaoSeccao = alturas[alturas.length - i].posicao;
        animarScroll(posicaoSeccao)
    });
});

$(window).scroll(function () {
    var winTop = $(window).scrollTop();
    for (var i = 0; i < alturas.length; i++) {
        var este = alturas[i];
        if (este.posicao > winTop) {
            $(lis).removeClass('active');
            $(alturas[i].elemento).addClass('active');
            break;
        }
    }
});

Example

    
09.04.2014 / 18:54