Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if element is between 30% and 60% of the viewport

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:

elements stacking side by side

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; } 
like image 619
Hook Avatar asked Apr 27 '15 09:04

Hook


People also ask

How do you check the element of a viewport?

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.

How do you tell your HTML to check the width of the viewport?

You can use the window. innerHeight property to get the viewport height, and the window. innerWidth to get its width.

How much of an element is visible in viewport?

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.

How do you know if an element has content?

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.


2 Answers

  1. Use scroll event handler on window
  2. Loop over all the li elements to check if the element is in the interested viewport
  3. Get the li 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>
like image 78
Tushar Avatar answered Sep 28 '22 05:09

Tushar


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>
like image 43
Andrea Ligios Avatar answered Sep 28 '22 05:09

Andrea Ligios