I am trying to add class or remove class on getting element top by using this demo. Here is the code as well:
$(document).ready(function () {
var sec1_offset = $("#sec1").offset();
var sec2_offset = $("#sec2").offset();
var sec3_offset = $("#sec3").offset();
var sec4_offset = $("#sec4").offset();
var sec5_offset = $("#sec5").offset();
var sec6_offset = $("#sec6").offset();
var sec7_offset = $("#sec7").offset();
$("section").scroll(function () {
if (sec4_offset.top < 100) {
alert("You Are in Sec 4");
}
});
});
I also change the $("section").scroll(function () {
to $(body).scroll(function () {
and $(document).scroll(function () {
but it didn't work. What am I doing wrong?
You can listen to the scroll
event of the window
object, scroll
event like the resize
event is fired so many times, for efficiency you can throttle the handler, ie the handler is executed after a specified timeout.
$(document).ready(function () {
var $sec = $("section"),
handle = null;
var $w = $(window).scroll(function () {
// clear the timeout handle
clearTimeout(handle);
// throttling the event handler
handle = setTimeout(function() {
var top = $w.scrollTop();
// filtering the first matched element
var $f = $sec.filter(function() {
return $(this).offset().top + $(this).height() >= top;
}).first().addClass('active');
$sec.not($f).removeClass('active');
}, 50);
}).scroll();
});
edit: If you want to add a class to another element, the most efficient way is using the index
method:
// Cache the object outside the `scroll` handler
var $items = $('#menu li');
// within the `setTimeout` context:
var $f = $sec.filter(function() {
return $(this).offset().top + $(this).height() >= top;
}).first();
$items.removeClass('active').eq( $sec.index($f) ).addClass('active');