4

I am making one big scroll page. And my nav is fixed positioned. I want to change the color (from black to white and vice versa) on the nav when it reaches specific sections on my page. It's because some of them are white, and some of them are dark - I want to make a contrast. I already made a class in css that should be toggled. But I am having difficulties using my code. Take a look at it:

https://jsfiddle.net/Lp27vuu4/

$(window).scroll(function (event) {
    var scroll = $(window).scrollTop();
        $('nav').toggleClass('light-mode',
            //add 'light-mode' class when div position match or exceeds else remove the 'light-mode' class.
            scroll >= $('.section2').offset().top
        );
    });

    //trigger the scroll
    $(window).scroll();//ensure if you're in current position when page is refreshed
body {
  margin: 0px;
  padding: 0px;
}

nav {
  width: 100%;
  position: fixed;
  text-align: center;
  padding-top: 20px;
  padding-bottom: 20px;
}

.light-mode {
    color: #fff;
}

.section1 {
   width: 100%;
   height: 400px;
   background-color: #fff;
   color: #000;
   padding: 100px;
}

.section2 {
   width: 100%;
   height: 400px;
   background-color: #000;
   color: #fff;
   padding: 100px;
}

.section3 {
   width: 100%;
   height: 400px;
   background-color: #fff;
   color: #000;
   padding: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
    <h3>navigation links</h3>
</nav>
<section class="section1">
    section 1
</section>
<section class="section2">
    section 2
</section>
<section class="section3">
    section 3
</section>

The conclusion:

My navigation by default is dark colored. When I reach the section that is dark I want to tell jQuery to add class .light-mode to <nav>. But when user goes off the section, I want it to go back to normal (so delete the class). In my solution it has issues:

  1. It seems to it is not going back to original when user is not on the section.
  2. The class is added just when user scrolls from top to bottom page. It looks on .offset().top. I want to make it more professional and universal. I want to add this class when each section is on screen not matter if its from bottom or top.
Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
DavidPL
  • 109
  • 1
  • 2
  • 10
  • What I recommend you to do is take a look at the code of Bootstrap: http://getbootstrap.com/javascript/#scrollspy They have a component called 'ScrollSpy' which exactly does what you want. – meavo Nov 10 '16 at 18:45
  • but, im not using bootstrap. I would prefer clean method, using just few lines of jquery. I know it is possible. – DavidPL Nov 10 '16 at 18:55
  • can you try this one: https://jsfiddle.net/Lp27vuu4/4/ – Tommy Schmidt Nov 10 '16 at 18:59
  • I didn't mean that you should use Bootstrap, but it's always good to look at other code to get a good understanding of what's going on. It's the same component you wish to build; so my advice is merely to be inspired by it. Not to use it directly. – meavo Nov 10 '16 at 21:09
  • @TommySchmidt - Your answer is my solution. Thank You. Please write it as an answer so I can mark this as a solved and give You +rep. Greetings. – DavidPL Nov 10 '16 at 21:31

2 Answers2

1

What you want to do is to add the class if scroll + the offset of your h3 is greater than the offset of the section and remove it if scroll + the offset of your h3 is greater than the offset of the section + it's height.

Check out this: https://jsfiddle.net/Lp27vuu4/4/

Tommy Schmidt
  • 1,224
  • 1
  • 16
  • 30
  • Thank You @Tommy - works good in my project :) – DavidPL Nov 11 '16 at 08:13
  • one more question. I am trying to add multiple class in within this one function, but its not working. How to add for example one more section to this code? ex. if (scroll + initialTopOffset >= $('.section2, .anotherSection').offset().top - not working. – DavidPL Nov 11 '16 at 22:52
  • you will need to track all sections that you want to add the class to. i would do this by adding each section a class (like isResponsive or so). then i'd get all elements that are using this class by calling document.getElememtsByClassName("isResponsive") and loop through them whenever i scroll and toggle the class when needed. i can give you an example later. for now i got to sleep. – Tommy Schmidt Nov 11 '16 at 22:57
  • Yep, I guess I will need Your help in coding it. I don't know even where to put the getElementsByClassName :/ . I just am starting my journey with jquery. edit: @Tommy, I noticed a little issue with Your script. Where user scrolls to the section that triggers the action, and from that point if he refresh the page - the script is going nuts. He is not doing the action on the correct div, but does it in different place (hard to explain). Like its not checking all the time if the element is on viewport or not. Anyway its not a big deal for me, so it is ok. – DavidPL Nov 12 '16 at 07:47
  • i updated the fiddle and added some comments: https://jsfiddle.net/Lp27vuu4/12/ if you have anything you dont understand, ask me. – Tommy Schmidt Nov 12 '16 at 08:07
  • Tommy, once again thank You !!!, Your comments are great - I understand the code more now thanks to them. – DavidPL Nov 12 '16 at 08:34
0

Waypoints is a popular plugin to trigger events on scroll.

http://imakewebthings.com/waypoints/

Place the waypoints js file in your project and link to it. Then do something like this below in your jQuery file

        function toggleClassFunction() {
            $('nav').toggleClass('light-mode');
        }


        var waypoint = new Waypoint({
        element: document.getElementById('id-of-element-when-scrolled-to-event-triggers'),
        handler: function(direction) {
            if (direction === 'down') {
                toggleClassFunction(); // the function that runs
                this.destroy() //runs the function once
            }
            else {

            }
        },
        offset: 250 //since the event triggers once the element reaches the top of the page, we
                    //sometimes need an offset. so in this example, when the element is 250px from
                    //the top of the page, the even triggers
        });
cup_of
  • 6,397
  • 9
  • 47
  • 94