<?xml version="1.0" encoding="UTF-8"?> 
<rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
        >
<channel>
  <title>asgaard</title>
  <description></description>
  <link>https://blog.asgaard.co.uk/2012/04/23/figure-out-which-element-is-scrolled-to-in-the-viewport-with-jquery</link>
  <lastBuildDate>Wed, 13 May 26 07:04:35 +0000</lastBuildDate>
  <language>en</language>
  <count>1</count>
  <offset>0</offset>
      <item>
    <title>Figure out which element is scrolled to jQuery</title>
    <link>https://blog.asgaard.co.uk/2012/04/23/figure-out-which-element-is-scrolled-to-in-the-viewport-with-jquery</link>
    <pubDate>Mon, 23 Apr 12 20:39:46 +0000</pubDate>
    <guid>https://blog.asgaard.co.uk/2012/04/23/figure-out-which-element-is-scrolled-to-in-the-viewport-with-jquery</guid>
    <description><![CDATA[
<p>
Does what it says on the tin. It takes a set of elements and tries to determine which one is featured most predominantly on the page. Change the $sections selector (line 3) to target the element-set of your choice, or rewrite as a plugin :)  
<p>
Towards the bottom, the element which is deemed to be in view will be given a &#039;highlight&#039; class.
<p>
Note that we are binding directly to the scroll event which is generally a bad idea. Whether it is a bad idea for you depends upon various factors. If you find it negative impacts performance on your page, factor out the scroll event and call it after a short timer (and cancel the timer on the next scroll).
<p>
<pre>(function() {
  &quot;use strict&quot;;
  var $sections = $('.panel'),
      $sectionsReversed = $($sections.get().reverse()),
      $last = $({});
  
  $(window).scroll(function(ev) {
    var pos = $(document).scrollTop(), 
        $nearest = $sections.eq(0),
        amount = 0; // amount of the screen occupied
        
    // scrolled to extremes - take th</pre>[...]]]></description>
    <content:encoded><![CDATA[
<p>
Does what it says on the tin. It takes a set of elements and tries to determine which one is featured most predominantly on the page. Change the $sections selector (line 3) to target the element-set of your choice, or rewrite as a plugin :)  
<p>
Towards the bottom, the element which is deemed to be in view will be given a &#039;highlight&#039; class.
<p>
Note that we are binding directly to the scroll event which is generally a bad idea. Whether it is a bad idea for you depends upon various factors. If you find it negative impacts performance on your page, factor out the scroll event and call it after a short timer (and cancel the timer on the next scroll).
<p>
<pre>(function() {
  &quot;use strict&quot;;
  var $sections = $('.panel'),
      $sectionsReversed = $($sections.get().reverse()),
      $last = $({});
  
  $(window).scroll(function(ev) {
    var pos = $(document).scrollTop(), 
        $nearest = $sections.eq(0),
        amount = 0; // amount of the screen occupied
        
    // scrolled to extremes - take the top or bottom element as appropriate
    // There's a little bit of leeway on the bottom scroll detection as 
    // Firefox sometimes seems to lose a pixel.
    if (pos === 0 &amp;&amp; false)
      $nearest = $sections.eq(0);
    else if (pos &gt;= $(document).height() - $(window).height() - 10) {
      $nearest = $sectionsReversed.eq(0);
    }
    // otherwise do something a little cleverer
    else {
      var windowHeight = $(window).height(),
          start = pos,
          end = start + windowHeight;
      $sections.each(function() {
        // we're going to try to figure out which element
        // takes up the important parts of the screen.
        var $this = $(this),
            top = $this.offset()? $this.offset().top + $this.outerHeight() : //IE?
              $this.offset().top,
            bottom = $this.offset().top + $this.outerHeight(),
            topVisible = top &gt;= start &amp;&amp; top &lt;= end,
            bottomVisible = bottom &gt;= start &amp;&amp; bottom &lt;= end,
            candidateAmount = 0;
            

        if (top &lt;= start &amp;&amp; bottom &gt;= end) {
          // occupies entire screen
          // we have a winner
          $nearest = $this;
          amount = 1;
          return false;
        }
        // no part of the element visible - nope
        else if (!topVisible &amp;&amp; !bottomVisible) return;
        
        else if (topVisible &amp;&amp; bottomVisible) {
          // full element is visible. We'll take this one
          // since it's highest on the screen.
          amount = (bottom-top)/windowHeight;
          $nearest = $this;
          return false;
        }
        else if (bottomVisible) {
          // occupies part of the screen from the top down only
          candidateAmount = (bottom - start)/windowHeight;
        }
        else if (topVisible) {
          // occupies part of the screen from the bottom up only
          candidateAmount = (end - top)/windowHeight;
        }
        
        if (candidateAmount &gt; amount) {
          amount = candidateAmount;
          $nearest = $this;
        }
      });
    }
    
    if ($last !== $nearest) {
      $last.removeClass('highlight');
      $nearest.addClass('highlight');
      $last = $nearest;
    }
  });
  $(window).trigger('scroll');
})();</pre>]]></content:encoded>
  </item>
  </channel>
</rss>