JavaScript位置:window&client&offset&scroll&MouseEvent&getBoundingClientRect&计算任意元素滚动条宽度

Window:

window.innerWidth:浏览器viewport视口宽,包括垂直滚动条

window.innerHeight:浏览器视口高,包括水平滚动条

window.outerWidth: 获取浏览器窗口外部的宽度。表示整个浏览器窗口的宽度,包括侧边栏(如果存在)、窗口镶边(window chrome)和调正窗口大小的边框

window.outerHeight:获取整个浏览器窗口的高度(单位:像素),包括侧边栏(如果存在)、窗口镶边(window chrome)和窗口调正边框(window resizing borders/handles)

client:

 clientWidth:

对于body元素:滚动条在margin之外。clientWidth = content + padding

 

 

对于非body元素:滚动条在padding之内。

如果滚动条不存在,则clientWidth = content+padding

如果有滚动条。

假设元素右边有垂直滚动条。

如果paddingRight>=滚动条宽度,滚动条默认在padding中,则clientWidth包括滚动条(但因为在padding里所以不必额外计算),clentWidth = content+padding

如果paddingRight< 滚动条宽度,滚动条会挤占content空间,此时clientWidth不包括滚动条,clientWidth = content + padding - scrollWidth

综上,clientWidth到底包不包括滚动条,取决于padding和滚动条的大小关系,在默认情况下,如果paddingRight >=滚动条宽度就包括;小于就不包括,就要减去滚动条宽度

场景1:不存在滚动条,padding-right为100时,clientWidth = content + padding

 

 

场景2:存在滚动条,但padding为0时,clientWidth = content + padding - scrollWidth

场景3:存在滚动条,但padding小于滚动条宽度时,clientWidth = content + padding - scrollWidth

 

 

clientHeight:

类比同上。

clientLeft/clientTop:

元素的左border宽度,当文字方向为右至左且出现滚动条时(direction: rtl),需要加上滚动条宽度

clientLeft = border Width + scrollbar Width(对于行内元素这个值为0)

clientTop = borderTop

 

计算元素滚动条宽度:

  • 对于非body元素,滚动条默认占padding的空间, 当padding没有设置或者已经设置但是宽度小于滚动条, 那么多余的宽度就会挤占content宽度
  • 对于body元素,chrome的body缺省margin值是8px,浏览器滚动条处于body元素的margin之外
  • elem.offsetWidth - elem.borderLeftWidth - elem.borderRightWidth - elem.clientWidth
export default class myUtils {
     // 计算元素滚动条宽度(默认clientWidth包括滚动条的情况)
     static getScrollWidth(elemOrSelect) {
        if (!elemOrSelect) return;
        if (elemOrSelect.constructor === String) 
       elemOrSelect = document.querySelector(elemOrSelect); //参数为html或body时 if (/BODY|HTML/.test(elemOrSelect.nodeName)) { elemOrSelect.style.margin = 0; return window.innerWidth - elemOrSelect.clientWidth; } //兼容IE var style = elemOrSelect.currentStyle ? elemOrSelect.currentStyle : getComputedStyle(elemOrSelect).style; //获取某个元素滚动条宽度 var width = elemOrSelect.offsetWidth - Math.ceil(parseFloat(style.borderLeftWidth)) - Math.ceil(parseFloat(style.borderRightWidth)) - elemOrSelect.clientWidth; return width; } }

 

offsetWidth/offsetHeight/offsetLeft/offsetTop:

offsetWidth/Height:

offsetWidth/offsetHeight: content + padding + border,包含滚动条,但滚动条包含在元素padding中,所以不参与计算

offsetParent/offsetTop/offsetWidth:

基于offsetParent确定距离,当祖先元素有定位属性时,offsetParent为最近的定位祖先元素,当offsetParent没有定位时,offsetParent为body。

当offsetParent为body时,offsetTop = margin + border + clientParentTop

当offsetParent存在且不为body时,offsetTop为相对于定位祖先元素(offsetParent)顶端的距离

screen

screenWidth/screenHeight:返回元素的实际宽/高,当元素的实际宽高大于可视宽高时依然如此。而clientWidth/Height则返回元素的时可视窗口内的可见宽高,最大不超过视窗宽高。

screenLeft/screenTop:返回滚动条滚动的距离

一张经典的图片:

 

MouseEvent

e.clientX/e.clientY:鼠标焦点相对于视口的距离

e.offsetX/e.offsetY:鼠标焦点相对于元素左上角border开始的坐标

e.pageX/e.pageY:鼠标焦点相对于文档左上角的坐标

e.screenX/e.sreenY:鼠标焦点相对于屏幕左上角的坐标

 

getBoundingClientRect():

返回包一个元素DomRect对象,该对象包含了位置相关属性:left、right、top、bottom、height、width

除了width和height,其他属性都是相对于可视窗口的左上角的距离。

 

posted @ 2020-02-09 15:08  IslandZzzz  阅读(472)  评论(0编辑  收藏  举报