Javascript基础篇之各种宽高属性及应用

在Javascript的开发过程中,我们总会看到类似如下的边界条件判断(懒加载):


const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;   

const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

if( scrollTop + window.innerHeight >= scrollHeight + 50) {

  console.log('滚动到底了!')

}

这些获取滚动状态的属性,可能我们咋一看能够理解,不过时间久了立马又忘记了。这是因为这些获取各种宽高的属性api及其的多,而且几乎都存在兼容性写法。一方面很难记,更重要的是不好理解。下面通过选取常用的几个来讲述下具体api的区别。

一 挂在window上的

window上最常用的只有window.innerWidth/window.innerHeight、window.pageXOffset/window.pageYOffset.

其中,window.innerWidth/windw.innerHeight永远都是窗口的大小,跟随窗口变化而变化。window.pageXOffset/window.pageYOffset是IE9+浏览器获取滚动距离的,实质跟document.documentElement/document.body上的scrollTop/scrollLeft功能一致,所以日常都使用兼容写法:


const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;

二 挂在document上的

1 clientWidth/clientHeight:元素内部的宽高.

记住公式:


clientWidth/clientHeight = padding + content宽高 - scrollbar宽高(如有滚动条)

2 offsetWidth/offsetHeight

个人觉得这个名字有点误导人,压根没有偏移的意思,记住公式即可:


offsetWidth/offsetHeight = clientWidth/clientHeight(padding + content) + border + scrollbar

由上述公式,可以得到第一个示例,即"获取滚动条的宽度(scrollbar)":


const el = document.querySelect('.box')

const style = getComputedStyle(el, flase)//获取样式

const clientWidth = el.clientWidth, offsetWidth = el.offsetWidth

//parseFloat('10px', 10) => 10

const borderWidth = parseFloat(style.borderLeftWidth, 10) + parseFloat(style.borderRightWidth, 10)

const scrollbarW = offsetWidth - clientWidth - borderWidth

3 offsetTop/offsetLeft

这两个才是真的意如其名,指的是元素上侧或者左侧偏移它的offsetParent的距离。这个offsetParent是距该元素最近的position不为static的祖先元素,如果没有则指向body元素。说白了就是:"元素div往外找到最近的position不为static的元素,然后该div的边界到它的距离"。

由此,可以得到第二个示例,即"获得任一元素在页面中的位置":


const getPosition = (el) => {

  let left = 0, top = 0;

  while(el.offsetParent) {

    //获取偏移父元素的样式,在计算偏移的时候需要加上它的border

    const pStyle = getComputedStyle(el.offsetParent, false);

    left += el.offsetLeft + parseFloat(pStyle.borderLeftWidth, 10);

    top += el.offsetTop + parseFloat(pStyle.borderTopWidth, 10);

    el = el.offsetParent;

  }

  return { left, top }

}

综上,结合getBoundingClientRect()得到综合示例"元素是否在可视区域":


function isElemInViewport(el) {

  const rt = el.getBoundingClientRect();

  return (

    rt.top >=0 &&

    rt.left >= 0 &&

    rt.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&

    rt.right <= (window.innerWidth || document.documentElement.clientWidth)

  )

}

其中,getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置:

clipboard

本文收录在个人的Github上https://github.com/kekobin/blog/issues/1,觉得有帮助的,欢迎start哈!

你可能感兴趣的:(Javascript基础篇之各种宽高属性及应用)