Rob
Rob

Reputation: 6370

Check if element with class is visible in viewport

I'm trying to detect if a class is currently visible in the viewport. I'm using this answer (can't get a reply to my question). The original post used ID's instead of classes, I've changed it to detect a class called .white-section which is repeated down the page.

At the moment it only detects the first .white-section, how can I get it to detect them all as they come and go into the viewport?

$('#content').scroll(function() {
    var top_of_element = $(".white-section").offset().top;
    var bottom_of_element = $(".white-section").offset().top + $(".white-section").outerHeight();
    var bottom_of_screen = $(window).scrollTop() + $(window).height();
    var top_of_screen = $(window).scrollTop();

    if((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
         $('.header-container').addClass('.alt-menu');
    }
    else {
        $('.header-container').removeClass('.alt-menu');
    }
});

This is how the html is setup:

<div class="header-container"></div>

<div class="white-section"></div>
<div class="white-section"></div>
<div class="white-section"></div>
<div class="white-section"></div>
<div class="white-section"></div>

Upvotes: 2

Views: 1605

Answers (1)

Taplar
Taplar

Reputation: 24965

Give the following a try. It loops over the elements to try to find any that match your conditional and if any do, it adds the class. I also added some slight throttling to the solution and also cached the lookups so that the scroll event will be faster.

(function($) {
  var scrollingIsThrottled = false;
  var $allWhiteSections = $(".white-section");
  var $window = $(window);
  var $headerContainer = $('.header-container');

  $('#content').scroll(function() {
    if (!scrollingIsThrottled) {
      scrollingIsThrottled = true;

      var $whiteSpaceMatchingExpression = $allWhiteSections.filter(function() {
        var $this = $(this);
        var top_of_element = $this.offset().top;
        var bottom_of_element = $this.offset().top + $this.outerHeight();
        var bottom_of_screen = $window.scrollTop() + $window.height();
        var top_of_screen = $window.scrollTop();

        return ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element));
      });
      
      if ($whiteSpaceMatchingExpression.length) {
        $headerContainer.addClass('alt-menu');
      } else {
        $headerContainer.removeClass('alt-menu');
      }
      
      scrollingIsThrottled = false;
    }
  });
}(jQuery));

Upvotes: 2

Related Questions