Skip to content
Advertisement

Changing color of DIV by scrolling another DIV’s with specific classes (margin/padding problem)

I’m currently working on a project where the logo color should change depending on the background color.

My only problem is the following: The Logo is switching to the class “inverted” if it scrolls over the black bg02 DIV. Up to here everything is working fine. But if I set a margin and/or padding to the bg02 DIV, than the Logo switches not right anymore (too early in and out). If there is no margin/padding, than it works like a charm.

I’ve tried it with offsetHeight instead of normal height, but it doesn’t work. Can u help me?

$(document).on("scroll", function() {
    // Use logo position:
    var scrollPos = $(document).scrollTop() + $("#logo").position().top + ($("#logo").height() / 2)
    // Or use position from window top:
    // var scrollPos = $(document).scrollTop();
    $('.bg02').each(function() {
        var refElement = $(this);
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.innerHeight() > scrollPos) {
            $('#logo').addClass("inverted");
            // found one, so exit .each
            return false;
        } else {
            $('#logo').removeClass("inverted");
        }
    });
});
#logo {
    position: fixed;
    top: 20px;
    left: 5%;
    z-index: 100;
    font-size: 26px;
    font-weight: 700;
    color: #000;
}

#logo.inverted {
    color: #fff;
}

.bg01, .bg02 {
    position: relative;
    width: 100%;
    height: 600px;
    margin: 60px auto;
    padding: 40px 0 40px 0;
}

.bg01 {
    background: #fff;
}

.bg02 {
    background: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div id="logo">Logo</div>


<div class="bg01"></div>

<div class="bg02"></div>

<div class="bg01"></div>

<div class="bg02"></div>

<div class="bg01"></div>

<div class="bg02"></div>

Advertisement

Answer

It looks like you didn’t take into account the margin in your calculations. Padding won’t give you any problems. This will probably work,even though I don’t know how effective it is to do these checks for every “.bg02” element.

$(document).on("scroll", function() {
    // Use logo position:
    var scrollPos = $(document).scrollTop() + $("#logo").position().top + ($("#logo").height() / 2)
    // Or use position from window top:
    // var scrollPos = $(document).scrollTop();
    $('.bg02').each(function() {
        var refElement = $(this);
        var margin = parseInt(refElement.css("margin-top"));
        if (refElement.position().top <= scrollPos - margin  && refElement.position().top + refElement.innerHeight() + margin > scrollPos) {
            $('#logo').addClass("inverted");
            // found one, so exit .each
            return false;
        } else {
            $('#logo').removeClass("inverted");
        }
    });
});
#logo {
    position: fixed;
    top: 20px;
    left: 5%;
    z-index: 100;
    font-size: 26px;
    font-weight: 700;
    color: #000;
}

#logo.inverted {
    color: #fff;
}

.bg01, .bg02 {
    position: relative;
    width: 100%;
    height: 600px;
    margin: 60px auto;
    padding: 40px 0 40px 0;
}

.bg01 {
    background: #fff;
}

.bg02 {
    background: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div id="logo">Logo</div>


<div class="bg01"></div>

<div class="bg02"></div>

<div class="bg01"></div>

<div class="bg02"></div>

<div class="bg01"></div>

<div class="bg02"></div>
Advertisement