– 关注前端和node js,分享福利和心得!

js中的各种距离

js中的各种距离

js中各种距离很容易混淆,再加上各种兼容问题,非常容易出错。

style.width/height

::: tip 提示

  • style.width/height只能获取内联样式中的宽高,
  • style.width/height=content,不包含margin、padding、border的。
  • style.width/height获取的值是string,并且带单位px(em,rem)。 :::
    <style>
      #box1{
          width:20px;
          height:20x;
      }
    </style>
    <div id="box1" style="width:10em;height:100px;margin:10px;padding:10px;border:1px solid #ddd;"></div>
    <script>
      var box1=document.getElementById('box1')
      console.log(box1.style.width,box1.style.height)//100px,100px
    </script>

    clientWidth/clientHeight

    ::: tip 注意
  • clientWidth/clientHeight获取的是可视区域的宽高,包括屏幕和dom元素的可视区域。
  • clientWidth/clientHeight=content+padding ,如果有滚动条,不包括滚动条
  • 常规方式window.innerWidth/innerHeight,IE9/IE8及以下:怪异模式,document.body.clientWidth/clientHeight,标准模式,document.documentElement.clientWidth/clientHeight
  • 在怪异模式下,document.body.clientWidth/clientHeightdocument.documentElement.clientWidth/clientHeight都能获取到正确的值,但是在标准模式下document.body.clientHeight获取的值<mark>不准确</mark>,document.body.clientWidthdocument.documentElement.clientWidth/clientHeight都能获取到正确的值。
  • clientWidth/clientHeight获取到的值是number,没有单位 :::
    // 获取可视区域的宽高
    function getViewportSize(){
      if(window.innerWidth){
          return {
              width:window.innerWidth,
              height:window.innerHeight
          }
      }else{
          // 这里是不能用||运算符的
          if(document.compatMode==="BackCompat"){
          // 怪异模式
          return {
              width:document.body.clientWidth,
              height:document.body.clientHeight
          }
      }else{
          // 标准模式
          return {
              width:document.documentElement.clientWidth,
              height:document.documentElement.clientHeight
          }
      }
      }
    

}


## offsetWidth/offsetHeight
::: tip 注意
+ offsetWidth/offsetHeight获取的是元素的实际宽高。
+ offsetWidth/offsetHeight=content+padding+border+滚动条
+ 如果有滚动条,包括滚动条(比如div宽度100,在有垂直滚动条的时候,获取的offsetWidth=83,因为滚动条的默认宽度为17)
+ 在没有滚动条的时候,offsetWidth/offsetHeight和clientWidth/clientHeight获取的值相等
:::

```js
// 获取元素的宽高
function getOffsetSize(){
    return {
        width:document.body.offsetWidth,
        height:document.body.offsetHeight
    }
}

scrollWidth/scrollHeight

::: tip 注意

  • scrollWidth/scrollHeight获取的是实际内容的宽高,比如div盒子的宽度高度是100px,里面内容高度是200px,这个时候会出现垂直滚动条,scrollHeight=200
  • scrollWidth/scrollHeight=content+padding
  • 如果有滚动条,不包括滚动 :::
<style type="text/css">
    *{
        margin:0;
        padding:0;
    }
    #box1{

        width: 100px;
        height: 100px;
        padding: 20px;
        margin: 20px;
        border:2px solid #333;
        background: red;
        overflow: auto;
    }
    #box2{
        width: 50px;
        height: 500px;
        padding: 10px;
        margin:10px;
        border:1px solid #ddd;
        background: green;
    }
</style>
<body>
    <div id="box1">
        <div id="box2"></div>
    </div>

<script type="text/javascript">
    var box1=document.getElementById('box1')
    var box2=document.getElementById('box2')
    console.log(box1.scrollWidth)//100+20*2-17=123
    console.log(box1.scrollHeight)//20*2+500+10*2+10*2+1*2=582
    console.log(box2.scrollWidth)//50+10*2=70
    console.log(box2.scrollHeight)//500+10*2=520
</script>
</body>

getBoundingClientRect()

::: tip 注意

  • getBoundingClientRect()获取的是元素的宽度和上下左右的距离集合。
  • getBoundingClientRect()获取的值可能带小数,在某些情况下要特别注意。
  • 上面都是通过属性来获取宽高的,getBoundingClientRect()是通过方法获取的。
  • getBoundingClientRect.width/height=content+padding+border
  • getBoundingClientRectwidth/height和offsetWidth/height相同 :::
console.log(box1.getBoundingClientRect())
// 获取的结果为
// {bottom: 164
// height: 144
// left: 20
// right: 164
// top: 20
// width: 144
// x: 20
// y: 20}

scrollTop/scrollLeft

::: tip 注意

  • scrollTop/scrollLeft 获取滚动条向上/向左滚动的距离
  • 获取滚动距离的方式有很多,常规方式 window.pageYOffset/pageXOffset ,IE9及IE8以下,document.body.scrollTop/scrollLeft或者document.documentElement.scrollTop/scrollLeft,不常规的方式 window.scrollY/scrollX
  • 在怪异模式下,document.documentElement.scrollTop=0,在标准模式下,document.body.scrollTop=0 :::
// 获取滚动条的滚动距离
function getScrollOffset(){
    if(window.pageYOffset){
        return {
            top:window.pageYOffset,
            left:window.pageXOffset
        }
    }else{
        return {
            // 因为这两种方式是互斥的,所以这里使用||或者+都可以
            top:document.body.scrollTop||document.documentElement.scrollTop,
            left:document.body.scrollLeft||document.documentElement.scrollLeft
        }
    }
}

offsetTop/offsetLeft

::: tip 注意

  • offsetTop/offsetLeft获取当前元素到父级元素上边和左边的距离
  • 如果所有父级元素都没有使用定位(relative,absolute,fixed),offsetTop/offsetLeft就是到页面顶部的距离
  • 如果父级元素使用了定位,offsetTop/offsetLeft获取到的就是当前元素到父级元素直接的距离 :::

案例说明

::: danger 注意 在上面的例子中,大部分都是获取网页的宽高,就会存在window、document.body、document.documentElement这样的写法,如果是获取某个元素el的宽高,直接el.clientWidth、el.scrollWidth、el.offsetWidth这样写就行了。 :::

总结

  • 上面获取到的宽高都不包括margin值,(在有滚动条的时候,获取父元素的scrollWidth/scrollHeight时,子元素的内容要加子元素margin值)
  • style.width/height基本很少使用,因为很少地方会写行内样式
  • offsetTop/offsetLeft获取的距离跟父元素的定位方式有关,如果要获取元素距离页面顶部和左边的距离,使用getBoundingClientRect()会更方便
  • clientWidth/clientHeight=content+padding; scrollWidth/scrollHeight=content+padding; offsetWidth/offsetHeight=content+padding+border;

最新文章

    热门文章

      前端无忧网 版权所有,保留一切权利 ! · 站点地图 © 2015-2020 · 粤ICP备18049878号-1 · 托管于 阿里云 & 七牛