JS 可视区域监听div展示, 曝光上报

在业务需求中会有,曝光上报这样的需求, 需要计算滚动条和页面可视区域来进行计算,直接粘 代码,大家拿去用吧,vue中离开当前页面一定要清空监听.

 

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>曝光上报计算</title>
    <!-- <script src="./flexible.js" type="text/javascript" charset="utf-8"></script> -->
    <style type="text/css">
      * {
        box-sizing: border-box;
      }

      li,
      ul {
        list-style: none;
      }

      .wbox {
        width: 100%;
        min-height: 100vh;
        background: #86A5AD;
      }

      .yh4 {
        width: 100%;
        height: 200px;
        background: beige;
        border-bottom: 1px solid #333333;
        padding: 20px;
        display: flex;
        justify-content: space-between;
      }

      .yh4 li {
        width: 20%;
        height: 100%;
        float: left;
        border: 1px solid #333333;
        background-color: aquamarine;
      }

      .yh2 {
        width: 100%;
        height: 200px;
        background: beige;
        border-bottom: 1px solid #333333;
        padding: 20px;
        display: flex;
        justify-content: space-between;
        margin-bottom: 0.266666rem;
      }

      .yh2 li {
        width: 46%;
        height: 100%;
        float: left;
        border: 1px solid #333333;
        background-color: aqua;
      }

      .yh1 {
        width: 100%;
        height: 200px;
        background: beige;
        border-bottom: 1px solid #333333;
        padding: 20px;
        display: flex;
        justify-content: space-between;
        margin-bottom: 0.266666rem;
      }

      .yh1 li {
        width: 100%;
        height: 100%;
        float: left;
        border: 1px solid #333333;
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <div class="wbox">
      <ul class="yh1 dom-exposure" data-id="yh1_11" data-id="yh1_11">
        <li>id: yh1_11 </li>
      </ul>
      <ul class="yh1 dom-exposure" data-id="yh1_21">
        <li>id: yh1_21 </li>
      </ul>
      <ul class="yh1 dom-exposure" data-id="yh1_31">
        <li>id: yh1_31 </li>
      </ul>
      <ul class="yh1 dom-exposure" data-id="yh1_41">
        <li>id: yh1_41 </li>
      </ul>
      <ul class="yh4 dom-exposure" data-id="yh4_1,yh4_12,yh4_13,yh4_14">
        <li>id: yh4_1</li>
        <li>id: yh4_12</li>
        <li>id: yh4_13</li>
        <li>id: yh4_14</li>
      </ul>
      <ul class="yh2 dom-exposure" data-id="yh2_1,yh2_12">
        <li>id: yh2_1</li>
        <li>id: yh2_12</li>
      </ul>
      <ul class="yh4 dom-exposure" data-id="yh4_21,yh4_22,yh4_213,yh4_214">
        <li>id: yh4_21</li>
        <li>id: yh4_22</li>
        <li>id: yh4_213</li>
        <li>id: yh4_214</li>
      </ul>
      <ul class="yh2 dom-exposure" data-id="yh2_21,yh2_23">
        <li>id: yh2_21</li>
        <li>id: yh2_23</li>
      </ul>
      <ul class="yh4 dom-exposure" data-id="yh4_31,yh4_312,yh4_313,yh4_314">
        <li>id: yh4_31</li>
        <li>id: yh4_312</li>
        <li>id: yh4_313</li>
        <li>id: yh4_314</li>
      </ul>
      <ul class="yh2 dom-exposure" data-id="yh2_31,yh2_32">
        <li>id: yh2_31</li>
        <li>id: yh2_32</li>
      </ul>


    </div>
  </body>
</html>
<script type="text/javascript">
  var timer, m1, m2;
  var domexposurearr = document.querySelectorAll(".dom-exposure");
  console.log(domexposurearr);

  // 退出和注销时候需要 将 window.onscroll =  null;

  window.onscroll = function() {
    // 滚动
    clearTimeout(timer) // 每次滚动前 清除一次
    timer = setTimeout(function() {
      // 停止滚动时上报
      domexposurearr.forEach((eldom) => {
        if (isElementInViewport(eldom)) {
          // 曝光上报
          console.log(eldom.dataset.id)
        }
      });
    },500)
  };



  function isElementInViewport(el) {
    // 判断是否在可视区域
    let rect = el.getBoundingClientRect();
    let width_st = rect.width / 2,
      height_st = rect.height / 2;
    let innerHeight = window.innerHeight,
      innerWidth = window.innerWidth;
    if (rect.top <= 0 && rect.height > innerHeight ||
      rect.left <= 0 && rect.width > innerWidth
    ) {
      return rect.left * rect.right <= 0 ||
        rect.top * rect.bottom <= 0
    }

    return (
      rect.height > 0 &&
      rect.width > 0 &&
      ((rect.top >= 0 && rect.top <= innerHeight - height_st) ||
        (rect.bottom >= height_st && rect.bottom <= innerHeight)) &&
      ((rect.left >= 0 && rect.left <= innerWidth - width_st) ||
        (rect.right >= width_st && rect.right <= innerWidth))
    );
  }
</script>

 

posted @ 2022-03-02 15:14  Ferdinand_包子君  阅读(338)  评论(0编辑  收藏  举报