My attempt in vanilla JS (tested on Chrome and Firefox)
JsFiddle demo
Note, this implementation is just a proof of concept and should be adjusted in order to properly work on different older browser. I tried to improve the performance by debouncing the scroll event (the requestAnimationFrame performs the check while the user is scrolling)
When the fixed div reaches the footer a class is toggled and the element turns so that position: absolute is set via CSS (I've done some minor tweaks on the style also for the footer)
Javascript
(function(div, footer) { var idleScrolling = true, scrollTop = 0, intvScrolling; var fr = footer.getBoundingClientRect(); var dr = div.getBoundingClientRect(); var checkFixedDivPosition = function() { var bottomEdge; if (!idleScrolling) { /* user is scrolling, get the scrollTop position */ scrollTop = document.documentElement.scrollTop || document.body.scrollTop; bottomEdge = dr.top + dr.height + scrollTop; div.classList.toggle('absolute', bottomEdge >= fr.top); /* set timeout to detect the end of the scroll and to avoid useless computation */ intvScrolling = setTimeout(function() { idleScrolling = true; }, 250); window.requestAnimationFrame(checkFixedDivPosition); } }; window.addEventListener('scroll', function() { /* clear timeout */ clearInterval(intvScrolling); intvScrolling = null; /* if the user starts to scroll then check elements */ if (idleScrolling) { idleScrolling = false; checkFixedDivPosition(); } idleScrolling = false; }); }( document.getElementById("fixedDiv"), document.getElementById("footer") ));
Timeline snapshots (while scrolling)
Vanilla-JS (debounced) approach:
FPS is generally high (green step function) painting and rendering events are minimal. Also the javascript area (yellow) is reasonably small. The red blocks above FPS are long (junk) frames

jQuery approach (for comparison)
