欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript判斷元素是否在可視區(qū)域的三種方法

 更新時(shí)間:2023年12月07日 09:58:27   作者:WebGirl  
這這篇文章給大家總結(jié)了JavaScript判斷元素是否在可視區(qū)域的三種方法,getBoundingClientRect,IntersectionObserver和offsetTop、scrollTop這三種方法,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下

方法1:getBoundingClientRect

用法

let domRect = dom.getBoundingClientRect();

DOMRect:{
  x/left:視圖原點(diǎn)(左上角)距離dom左邊框距離,
  y/top:視圖原點(diǎn)(左上角)距離dom上邊框距離,
    right:視圖原點(diǎn)(左上角)距離dom右邊框距離,
    bottom:視圖原點(diǎn)(左上角)距離dom底邊框距離,
    width:dom的寬度,標(biāo)準(zhǔn)盒模型,width = 寬度+padding+border;怪異盒模型,width = 設(shè)置的寬度,
    height:dom的高度,
}

所以我們可以根據(jù)DOMRect的中的各個(gè)屬性來(lái)判斷dom是否在可視區(qū)域內(nèi)。

eg:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>getBoundingClientRect可視區(qū)域</title>
  <style>
    * {
      margin: 0
    }
    .circle-wrap {
      position: fixed;
      top: 50px;
      right: 50px;
      padding: 10px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      width: 140px;
      background: #fff;
    }

    .circle-wrap .circle {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: red;
    }

    .card-wrap {
      height: 2000px;
      width: 3000px;
      margin-top: 100px;
    }

    .card-wrap .card {
      width: 200px;
      height: 200px;
      padding: 20px;
      box-sizing: border-box;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      margin-top: 500px;
      margin-left: 500px;
    }
  </style>
</head>

<body>
  <div class="circle-wrap">
    <span>當(dāng)下方的卡片在可視區(qū)域內(nèi),我的圈圈是綠色,否則是紅色</span>
    <span class="circle"></span>
  </div>
  <div class="card-wrap">
    <div class="card">我是一個(gè)卡片</div>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js"></script>
  <script>
    const card = document.querySelector(".card");
    const circle = document.querySelector(".circle");
    const getBoundingClientRectJudge = () => {
      let domRect = card.getBoundingClientRect();
      console.log(domRect)
      let ch = document.documentElement.clientHeight;
      let cw = document.documentElement.clientWidth;
      let isInsert = true;
      if (domRect.bottom < 0 || domRect.top > ch || domRect.right < 0 || domRect.left > cw) {
        isInsert = false;
      }
      let background = null
      if (isInsert) {
        background = "green"
      } else {
        background = "red"
      }
      circle.style.background = background
    }
    window.addEventListener("scroll", _.throttle(getBoundingClientRectJudge, 500))
    getBoundingClientRectJudge()
  </script>
</body>

</html>

效果圖:

問(wèn)題

getBoundingClientRect并不能滿足所有情況,甚至說(shuō),它只能滿足一種情況的判斷,那就是需要判斷的那個(gè)dom節(jié)點(diǎn),它只身處在一個(gè)滾動(dòng)條的情況下。什么意思呢,就是它所有的祖先節(jié)點(diǎn),加起來(lái)的滾動(dòng)條只有1個(gè),如果它父節(jié)點(diǎn)有滾動(dòng)條,父父節(jié)點(diǎn)也有滾動(dòng)條,那這種方法就不好用了,請(qǐng)看示例:

下面展示的結(jié)果是錯(cuò)誤的,圈圈應(yīng)該是紅色才對(duì)。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>getBoundingClientRect可視區(qū)域</title>
  <style>
    * {
      margin: 0
    }

    body {
      height: 2000px;
      width: 3000px;
    }

    .circle-wrap {
      position: fixed;
      top: 50px;
      right: 50px;
      padding: 10px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      width: 140px;
      background: #fff;
    }

    .circle-wrap .circle {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: red;
    }

    .card-wrap {
      height: 400px;
      width: 600px;
      margin-top: 100px;
      margin-left: 100px;
      border: 1px solid green;
      overflow: auto;
    }

    .card-wrap .card {
      width: 200px;
      height: 200px;
      padding: 20px;
      box-sizing: border-box;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      margin-top: 500px;
      margin-left: 500px;
    }

    .head {
      width: 100%;
      height: 100px;
      background: pink;
      /* position: fixed; */
      top: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <!-- <div class="head"></div> -->
  <div class="circle-wrap">
    <span>當(dāng)下方的卡片在可視區(qū)域內(nèi),我的圈圈是綠色,否則是紅色</span>
    <span class="circle"></span>
  </div>
  <div class="card-wrap">
    <div class="card">我是一個(gè)卡片</div>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js"></script>
  <script>
    const card = document.querySelector(".card");
    const circle = document.querySelector(".circle");
    const getBoundingClientRectJudge = () => {
      let domRect = card.getBoundingClientRect();
      let ch = document.documentElement.clientHeight;
      let cw = document.documentElement.clientWidth;
      let isInsert = true;
      if (domRect.bottom < 0 || domRect.top > ch || domRect.right < 0 || domRect.left > cw) {
        isInsert = false;
      }
      let background = null
      if (isInsert) {
        background = "green"
      } else {
        background = "red"
      }
      circle.style.background = background
    }
    window.addEventListener("scroll", _.throttle(getBoundingClientRectJudge, 500))
    getBoundingClientRectJudge()
  </script>
</body>

</html>

由此,我們引出第二種方法,IntersectionObserver。

方法2:IntersectionObserver

用法

eg:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>getBoundingClientRect可視區(qū)域</title>
  <style>
    * {
      margin: 0
    }

    body {
      height: 2000px;
      width: 3000px;
    }

    .circle-wrap {
      position: fixed;
      top: 50px;
      right: 50px;
      padding: 10px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      width: 140px;
      background: #fff;
    }

    .circle-wrap .circle {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: red;
    }

    .card-wrap {
      height: 400px;
      width: 600px;
      margin-top: 100px;
      margin-left: 100px;
      border: 1px solid green;
      overflow: auto;
    }

    .card-wrap .card {
      width: 200px;
      height: 200px;
      padding: 20px;
      box-sizing: border-box;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      margin-top: 500px;
      margin-left: 500px;
    }
    .head{
      width: 100%;
      height: 100px;
      background: pink;
      /* position: fixed; */
      top:0;
      left: 0;
    }
  </style>
</head>

<body>
  <!-- <div class="head"></div> -->
  <div class="circle-wrap">
    <span>當(dāng)下方的卡片在可視區(qū)域內(nèi),我的圈圈是綠色,否則是紅色</span>
    <span class="circle"></span>
  </div>
  <div class="card-wrap">
    <div class="card">我是一個(gè)卡片</div>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js"></script>
  <script>
    const card = document.querySelector(".card");
    const circle = document.querySelector(".circle");
    const observer = new IntersectionObserver((changes) => {
      // changes是數(shù)組
      changes.forEach(one => {
        console.log(one)
        let isIntersecting = one.isIntersecting
        let background = null
        if (isIntersecting) {
          background = "green"
        } else {
          background = "red"
        }
        circle.style.background = background
      })
    })
    observer.observe(card)
    // console.log(observer)
    /* 取消觀察特定的元素:observer.unobserve(dom) */
    /* 對(duì)象停止監(jiān)聽(tīng)目標(biāo) observer.disconnect() */
  </script>
</body>

</html>

補(bǔ)充說(shuō)明

IntersectionObserver可以傳root,進(jìn)一步判斷dom是相對(duì)于哪個(gè)節(jié)點(diǎn),來(lái)判斷是否在可視區(qū)域內(nèi),默認(rèn)rootdocument

const observer = new IntersectionObserver((changes) => {
      console.log(changes)
      changes.forEach(one => {
        console.log(one)
        let isIntersecting = one.isIntersecting
        let background = null
        if (isIntersecting) {
          background = "green"
        } else {
          background = "red"
        }
        circle.style.background = background
      })
    },{root:document.querySelector(".card-wrap")})

方法3:offsetTop、scrollTop

說(shuō)明

  • offsetTop:元素的上外邊框至包含元素的上內(nèi)邊框之間的像素距離,其他方向相同
  • offsetWidth:元素兩端算上外邊框的寬度,其他方向相同
  • scrollLeftscrollTop:既可以確定當(dāng)前元素的滾動(dòng)狀態(tài),也可以設(shè)置元素的滾動(dòng)位置
  • scrollWidthscrollHeight:確定元素內(nèi)容的實(shí)際大小
  • clientWidth:元素內(nèi)容區(qū)寬度加上左右內(nèi)邊距寬度,即clientWidth = content + padding
  • clientHeight:元素內(nèi)容區(qū)高度加上上下內(nèi)邊距高度,即clientHeight = content + padding

使用

公式:

0 <= el.offsetTop - document.documentElement.scrollTop <= viewPortHeight

寫(xiě)法:

function isInViePortOfOne(el){
    const viewPortHeight = window.innerHeight || document.documentElement.clientHeight||document.body.clientHeight
    const offsetTop = el.offsetTop;
    const scollTop = document.documentElement.scrollTop
    const top = offsetTop - scollTop;
    return top <= viewPortHeight && top >= 0
}

以上就是JavaScript判斷元素是否在可視區(qū)域的三種方法的詳細(xì)內(nèi)容,更多關(guān)于JavaScript判斷元素是否在可視區(qū)域的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論