offsetTop, offsetWidth, offsetParent,clientWidth

382 阅读1分钟

1. offsetParent

当前元素上级元素中的定位元素或者 table,``td,``th,``body
注意: 该元素(或祖先元素)设置display: none,或者position: fixed 那么offsetParent返回null;
display: none,整个元素都不展示了,哪来的offsestParent

2. offsetWidth, offsetHeight

元素的宽度(高度),包括padding, border;

3. offsetTop, oosetLeft

距离当前元素的offsetParent的内边距

4. clientWidth, clientHeight

元素的内部宽度(包括padding,不包括border, margin,垂直滚动条 )
注意:当元素是html或者body,返回viewport的宽度(不包括任何滚动条)

image.png

顺便一提获取viewport的高度:

window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

5. 例子: 实现点击,根据元素的ID滚动到视口内;

<!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>Document</title>
  <style>
    .wrap {
      width: 300px;
      height: 300px;
      padding: 10px;
      border: 2px solid red;
      /* position: relative; */
    }
    .inner {
      width: 250px;
      height: 250px;
      border: 5px dashed pink;
      position: relative;
    }
    .one {
      width: 200px;
      height: 200px;
      background-color: green;
      padding: 2px;
      margin: 3px;
      border: 1px solid yellow;
      /* position: fixed; */
    }
    .txt {
      width: 100%;
      height: 20px;
    }
  </style>
</head>
<body>
  <section class="wrap" id="wrap" onclick="scrollToId('two')">
    <div class="inner" id="inner">
      <div class="one" id="one">dscdsacds</div>
    </div>
  </section>
  <div class="wrap" id="two" style="border-color: deeppink; margin-top: 200px;">two</div>
  <div class="wrap" id="three" style="border-color: deepskyblue; margin-top: 20px;">three</div>
  <div class="wrap" id="four" style="border-color: black; margin-top: 20px;">four</div>
  
  <script>
    function isExist(id) {
      if(!id) return false;
      return document.getElementById(id)
    }


    function getOffsetTop(el) {
      return el.offsetParent ? el.offsetTop + getOffsetTop(el.offsetParent) : el.offsetTop;
    }

    function isInViewport(el) {
      let viewportHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
      const top = getOffsetTop(el)
      console.log(123, top, viewportHeight)
      return top > 0 && top < viewportHeight;
    }


    function scrollToId(id) {
      let targetElement = isExist(id);
      let viewportHeight = window.innerHeight && document.documentElement.clientHeight && document.body.clientHeight;
      if(isInViewport(targetElement)) {  // 在视口内,滚动到页面顶部
        let y = getOffsetTop(targetElement);
        window.scrollTo({
          top: y,
          left: 0,
          behavior: 'smooth'
        })
      } else {   // 不在视口内,滚动到页面的一半位置
        let y = getOffsetTop(targetElement) - viewportHeight / 2;
        window.scrollTo({
          top: y,
          left: 0,
          behavior: 'smooth'
        })
      }
    }
    
  </script>
</body>
</html>