Check if element is between 30% and 60% of the viewport
- Use
scroll
event handler onwindow
- Loop over all the
li
elements to check if the element is in the interested viewport - Get the
li
position fromtop
and check if it is in the interested viewport section.
Changed the height of li
for demo purpose.
See the comments inline in the code.
$(document).ready(function() { // Get viewport height, gridTop and gridBottom var windowHeight = $(window).height(), gridTop = windowHeight * .3, gridBottom = windowHeight * .6; $(window).on('scroll', function() { // On each scroll check if `li` is in interested viewport $('ul li').each(function() { var thisTop = $(this).offset().top - $(window).scrollTop(); // Get the `top` of this `li` // Check if this element is in the interested viewport if (thisTop >= gridTop && (thisTop + $(this).height()) <= gridBottom) { $(this).css('background', 'red'); } else { $(this).css('background', 'gray'); } }); });});
ul { margin: 0; list-style-type: none; padding: 0;}ul li { width: 50px; height: 30px; background: #f5f5f5; float: left; margin: 10px; text-align: center; padding-top: 10px}ul li.middleviewport { background: red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script><ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> <li>19</li> <li>20</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> <li>19</li> <li>20</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> <li>19</li> <li>20</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> <li>16</li> <li>17</li> <li>18</li> <li>19</li> <li>20</li></ul>
Improved @Tushar's solution to make it work even after a resize of the window (a recalculation of the viewport is necessary each time, not only at the beginning), and to make it start already highlighted, without the need to scroll.
Also improved a bit the graphic of the example to highlight the interested area.
$(document).ready(function() { $(window).on('scroll', function() { var windowHeight = $(window).height(), gridTop = windowHeight * .3, gridBottom = windowHeight * .6; $('ul li').each(function() { var thisTop = $(this).offset().top - $(window).scrollTop(); if (thisTop > gridTop && (thisTop + $(this).height()) < gridBottom) { $(this).css('background', 'red'); } else { $(this).css('background', 'silver'); } }); }); $(window).trigger('scroll');});
ul { margin: auto;}ul li { width: 300px; height: 10px; background: silver; float: left; margin: 10px; list-style: none;}ul li.middleviewport { background: red;}#viewportMask { position: fixed; top: 30%; bottom: 40%; left: 0; right: 0; background: red; opacity: 0.2;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script><div id="viewportMask"></div><ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li></ul>
[[ This example checks if ANY part of the element is inside the specified region ]]
When you have the top and bottom coordinates of two boxes, you can check if the two boxes overlap by checking:
box1.top < box2.bottom && box1.bottom > box2.top
In the following example, box1 is the 30%-60% portion of window while box2 is each list item. Add debounce function and we have:
var timeout;$(window).on("load scroll resize", function() { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(function() { var $window = $(window), hitbox_top = $window.scrollTop() + $window.height() * .3, hitbox_bottom = $window.scrollTop() + $window.height() * .6; $("li").each(function() { var $element = $(this), element_top = $element.offset().top, element_bottom = $element.offset().top + $element.height(); $element.toggleClass("middle-viewport", hitbox_top < element_bottom && hitbox_bottom > element_top); }); }, 200);});
#overlay { position: fixed; left: 0; top: 30%; width: 100%; height: 30%; background-color: rgba(0, 192, 255, .5);}ul { padding: 0; text-align: center;}li { display: inline-block; margin: 10px; width: 200px; height: 200px; background-color: #F5F5F5;}li.middle-viewport { background-color: #FF0000;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><div id="overlay"></div><ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li></ul>