I am trying to change the color of <li>
elements when they are between 30% and 60% of the viewport.
So I have this grid of elements stacking side by side like this:
I ran into few plugins like Waypoints, Viewport Checker and few others but nothing good.
Any idea?
I am using a pretty simple structure :
JSFIDDLE
HTML
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title></title> <meta name="description" content=""> <meta name="author" content=""> <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/styles.css"> <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script> <script src="js/main.js"></script> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body> <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> </ul> </body> </html>
CSS:
ul { margin: auto; } ul li { width: 300px; height: 200px; background: #f5f5f5; float: left; margin: 10px; } ul li.middleviewport{ background:red; }
Summary. Use the getBoundingClientRect() method to get the size of the element and its relative position to the viewport. Compare the position of the element with the viewport height and width to check if the element is visible in the viewport or not.
You can use the window. innerHeight property to get the viewport height, and the window. innerWidth to get its width.
So even if it's a part of a element but it covers the full height of the screen, it should be 100% in viewport.
To check if an element contains specific text: Use the textContent property on the element to get the text content of the element and its descendants. Use the includes() method to check if the specific text is contained in the element. If it is, the includes() method returns true , otherwise false is returned.
scroll
event handler on window
li
elements to check if the element is in the interested viewportli
position from top
and check if it is in the interested viewport section.Demo:
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.
Running demo
$(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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With