PaulvdDool PaulvdDool - 8 months ago 44
jQuery Question

jquery detect overlap multiple sections

I'm trying to make my fixed navigation change color when it overlaps different parts of my website.
Much like the navigation on this website:

My html exists of divs and sections.

<li class="work">Work</li>
<li class="about">About</li>
<li class="contact">Contact</li>

<div id="red">

<section id="green">

<div id="blue">

<section id="yellow">

For the JS I use an overlaps library I found on github.

This jquery I added myself:

$(document).scroll(function() {

var contactColl = $('ul').overlaps('section');
$('ul')[contactColl.hits.length? 'addClass' : 'removeClass']('white');

var aboutColl = $('ul li.about').overlaps('section');
$('ul li.about')[aboutColl.hits.length? 'addClass' : 'removeClass']('white');

var workColl = $('ul').overlaps('section');
$('ul')[workColl.hits.length? 'addClass' : 'removeClass']('white');


Or view here on Codepen.

It works perfectly for the first section. But it ignores the second section. I get that it picks the first section it comes across, but I can't figure out how to make it work for the other section(s).

I tried naming the sections separately like this:

var contactColl = $('ul').overlaps('#green, #yellow');


var contactColl = $('ul').overlaps('#green');
$('ul')[contactColl.hits.length? 'addClass' : 'removeClass']('white');

var contactColl2 = $('ul').overlaps('#yellow');
$('ul')[contactColl2.hits.length? 'addClass' : 'removeClass']('white');

This just broke everything.

Can anybody help me with this?


The Overlaps plugin deals with only one object, over which your target overlaps. just little fix like this:

$.fn.overlaps = function(objs) {
    var elems = {targets: [], hits:[]};
    this.each(function() {
        var bounds = $(this).offset();
        bounds.right = bounds.left + $(this).outerWidth();
        bounds.bottom = + $(this).outerHeight();

          var obj = this;
          var compare = $(obj).offset();             
          compare.right = compare.left + $(obj).outerWidth();
          compare.bottom = + $(obj).outerHeight();

          if (!(compare.right < bounds.left ||
                compare.left > bounds.right ||
                compare.bottom < ||
       > bounds.bottom)
             ) {

    return elems;


Iterating thru' a collection of objects $(objs).each instead of taking just the first of them - will fix that.

Working demo