Search code examples
jquerybackground-color

Background colour doesn't change on all triggers


I want a fixed element to change its background colour depending on which section the user scrolls past. The code I have works on one section, but not others. As a test, I configured it to also change the background colour of the sections themselves, and it works.

$(window).scroll(function () {
    $(".section").each(function () {
        var box = $("#box");
        var BoxTop = box.position().top;
        var BoxBottom = BoxTop + box.outerHeight();
        var section = $(this);
        var sectionTop = section.position().top - $(window).scrollTop() + 15;
        var sectionBottom = section.position().top - $(window).scrollTop() + section.height();
        if ((sectionTop >= BoxTop && sectionTop <= BoxBottom) || (sectionTop <= BoxTop && sectionBottom >= BoxBottom) || (sectionBottom >= BoxTop && sectionBottom <= BoxBottom)) {
            section.css("background", "blue");
            box.css("background", "blue");
        } else {
            section.css("background", "red");
            box.css("background", "red");
        }
    });

});

Fiddle: http://jsfiddle.net/xo1Lyfnc/1/


Solution

  • The issue you are experiencing is because you are looping over all the sections, and are changing the background accordingly.

    Because you are not breaking out of the loop (when you match the section) the result will be overridden in the next iteration of the loop. This means, that the desired functionality will only work for the last .section on the page.

    To make it work for all your sections, simple break the loop after you match a section. In jQuery's each function you can do this by returning false.

    Your updated code:

    $(window).scroll(function () {
        $(".section").each(function () {
            var box = $("#box");
            var BoxTop = box.position().top;
            var BoxBottom = BoxTop + box.outerHeight();
            var section = $(this);
            var sectionTop = section.position().top - $(window).scrollTop() + 15;
            var sectionBottom = section.position().top - $(window).scrollTop() + section.height();
            if ((sectionTop >= BoxTop && sectionTop <= BoxBottom) || (sectionTop <= BoxTop && sectionBottom >= BoxBottom) || (sectionBottom >= BoxTop && sectionBottom <= BoxBottom)) {
                section.css("background", "blue");
                box.css("background", "blue");
                return false; // We found a match, so stop trying to match the other sections.
            } else {
                section.css("background", "red");
                box.css("background", "red");
            }
        });
    
    });
    

    A working fiddle