7张图搞懂浏览器所有视口距离属性!

lxf2023-03-20 18:19:01

开启AdminJS成长之旅!这是我参与「AdminJS日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

现有一个class名为mini-box的盒子,分别设置了宽高与内外边距、边框线:

// 父元素
.box{
    width: 100px;
    height: 100px;
    margin-top: 20px;
    margin-left: 20px;
    background-color: yellowgreen;
    display: flex;
    justify-content: center;
    align-items: center;
}
// 子元素
 .mini-box {
    width: 30px;
    height: 30px;
    padding: 1px;
    margin:3px;
    box-sizing: border-box;
    border: 2px solid #000;
    background-color: cyan;
 }

下面的所有系列都是以上面的盒子为基础去一一分析的。我们先了解一下如何获取下面元素系列的宽高度的?(以clientWidth为例)

// 方式
console.log(box.clientWidth);// box为元素id名称

// 方式二
console.log(document.getElementsByClassName('mini-box')[0].clientWidth);

可见元素client~系列

7张图搞懂浏览器所有视口距离属性!

盒子宽度30px,内边距设置为1px,外边距为3px,边框线为5px

  • clientWidthclientHeight元素可见宽高度,只包含内边距和内容宽度,但不包含边框线、外边距、滚动条。上面mini-box例子获取到的可见元素宽高:

    document.getElementsByClassName('mini-box')[0].clientWidth;// 20,30-5-5(减去左右边框)
    document.getElementsByClassName('mini-box')[0].clientHeight;// 20,30-5-5(减去上下边框)
    
  • clientLeftclientTop元素可见左边框宽度、上边框宽度

    document.getElementsByClassName('mini-box')[0].clientTop;// 5,上边框线宽度
    document.getElementsByClassName('mini-box')[0].clientLeft;// 5,左边框线宽度
    
  • getClientRects()获取元素占据页面的所有矩形区域。返回一个包含width、height、right、left、bottom、top六个属性。常用于获取鼠标位置,也就是实现放大镜效果。 7张图搞懂浏览器所有视口距离属性!

  • getBoundingClientRect()用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。获取到的属性与getClientRects()一致,细心地我们可能会问:既然属性都是一样,那么getClientRects与getBoundingClientRect究竟有什么不同的地方?

7张图搞懂浏览器所有视口距离属性! getClientRects返回的是一个DOMRectList数组,数组中每一个元素都是一个DOMRect对象,getBoundingClientRect返回的只是一个DOMRect对象。

页面偏移offset~系列

7张图搞懂浏览器所有视口距离属性!

  • offsetWidthoffsetHeight:返回的是元素布局的宽、高度,除了外边距,其他都包含(padding、border、width、滚动条宽度)。如果元素设置了css的width或height属性,那么这两个值分别为width、height`,通俗理解就是无视元素内任何距离。如果元素没有设置css的width或height属性,那么两个值分别为内容width+2 * padding-left+2 * border+scroll的width、height+2 * padding-top+2 * border+scroll的width

    document.getElementsByClassName('mini-box')[0].offsetWidth;// 30px
    document.getElementsByClassName('mini-box')[0].offsetWidth;// 30px
    
  • offsetLeftoffsetTop:返回的是元素布局距离的浏览器视口上边距离、浏览器左边距离。可以通俗理解为除了offsetWidth、offsetTop外left、top距离。

    document.getElementsByClassName('mini-box')[0].offsetLeft;// 55px=20+(100-30)/2
    document.getElementsByClassName('mini-box')[0].offsetLeft;// 55px=20+(100-30)/2
    
  • offsetParent获取距离该子元素最近的进行过定位的父元素(position:absolute  relative fixed),如果其父元素中不存在定位则offsetParent为:body元素。由于盒子mini-box盒子最近的父元素是box,但是它是没有定位,所以获取到的元素是body。注意地,如果该元素有定位,父元素没有定位时,offsetParent获取元素为null(firefox中为:body,其他浏览器返回为null),一句话理解:获取最近有定位的父元素,否则为body元素

    document.getElementsByClassName('mini-box')[0].offsetParent;// body元素信息
    

滚动距离scroll~系列

  • scrollWidthscrollHeight获取元素内容整体宽、高度,包含内容溢出不可见部分、内边距,不包含元素外边距、边框、滚动条,只是内容宽高度+内边距。比如下图获取scrollWidth = 2 * 1px(左右内边距)+256px内容宽度 = 258px。

    7张图搞懂浏览器所有视口距离属性!

  • scrollLeftscrollTop获取元素内容左边缘或上边缘与视图的距离,与滚动条有关。水平滚动条不动(scrollLeft=0),向右拉到尽头,元素内容向左隐藏了部分(隐藏部分宽度就是scrollLeft,如下图隐藏部分),scrollTop同理。

7张图搞懂浏览器所有视口距离属性!

  • scroll():滚动窗口至文档中的特定坐标。参数可为x、y,也可以为对象包含三个属性(x,y,behavior),behavior可单独设置为scroll-behavior有两个值smooth(滚动采用平滑过渡) | auto(立即滚动到指定位置)

  • scrollBy():在窗口中按指定的偏移量滚动文档。它也有三个属性。

  • scrollTo():滚动到文档中的某个坐标。

  • scrollIntoView():使元素滚动到可视区。它有三个属性behavior(滚动方式)、block(块级元素排列方式需要滚动的位置)、inline(行内元素排列方向要滚动到的位置)。

    {
    behavior:"auto"|"instant"|"smooth",// 默认 auto
    block:"start"|"center"|"end"|"nearest",// 默认 center
    inline:"start"|"center"|"end"|"nearest",// 默认 nearest
    }
    

window内置~XY系列

7张图搞懂浏览器所有视口距离属性!

注意地,如果设置可视窗口控制为移动端形式,不同浏览器获取到的inner ~与outer ~都是一样的,都是当前可视窗口的宽高。

  • innerWidth、innerHeight:浏览器的可视窗口的宽高。
  • outerWidth、outerHeight:浏览器窗口的宽高。
  • pageXOffset、pageYOffset:文档相对于窗口左上角的水平和垂直方向滚动的像素。
  • screen~系列:以当前浏览器窗口为基准,获取与屏幕之间的距离。
  • scroll~系列:以当前浏览器滚动视图为基准,获取距离可以参考上面的。

事件坐标~XY系列

7张图搞懂浏览器所有视口距离属性!

  • clientX、clientY:鼠标指针距离浏览器可视口x、y坐标。
  • screenX、screenY:鼠标指针距离电脑屏幕x,y坐标。
  • pageX、pageY:clientX和滚动条宽度,clientY同理。
  • offsetX、offsetY:获取最近有定位的父元素的左边距离、上边距离。
  • layerX、layerY:以有定位父元素(如果没有,则为Document对象)左上角为原点,定位事件x,y轴坐标。
  • movementX、movementY:当前事件和上一个mousemove事件之间鼠标在水平垂直方向上的移动值,currentEvent.movementX = currentEvent.screenX - previousEvent.screenX,movementY同理。

总结

  • 元素相关:client~系列获取元素边框边缘距离(clientLeft、clientTop,也就是边框线的宽度)、获取元素宽度(clientWidth、clientHeight)。
  • 偏移相关:offset~系列与浏览器视口相关,相对于浏览器视口获取距离。
  • 滚动相关:scroll~系列获取的是元素内容可见与溢出内容相关,相对于滚动视图获取距离。
  • 事件相关:通过事件获取,与事件相关。
  • window相关:元素有的~XY系列,它几乎有。它是以浏览器窗口为基准,获取窗口与屏幕的距离。