在开发中经常用到获取元素位置和大小的需求,我最近在vue2.x上写了一个图片查看组件,它有拖动,定点缩放功能,这就需要获取视口大小,元素位置和大小。
看了阮老师的相关文章,实现了这个组件,也顺便在阮老师的这篇文章基础上整理一下,方便日后查阅。
获取视口大小(宽高)
任何元素都有 clientHeight 和 clientWidth 属性,也可用来获取视口大小。
js
document.documentElement.clientHeight;
document.documentElement.clientWidth;
在大多数情况下,document.documentElement.clientWidth 都能返回正确的值, 但在IE6的quirks模式中,document.body.clientWidth返回正确的值,所以要做兼容处理。另外clientWidth 和 clientHeight 都是只读属性,不能对它们赋值。
// js
function getViewPortSize() {
if(document.compatMode === "BackCompat") {
return {
height: document.body.clientHeight,
width: document.body.clientWidth
}
} else {
return {
height: document.documentElement.clientHeight,
width: document.documentElement.clientWidth
}
}
}
如何x,y轴都没有出现滚动条,那么也可以用scrollWidth和scrollHeight,它表示视口宽高加滚动区域的大小,所以在没有滚动条时,它就表示视口大小。
这两个属性跟 clientHeight 和 clientWidth 一样,所有元素都有,也是只读属性。
// js
function getPageArea() {
if(document.compatMode === "BackCompat") {
return {
height: document.body.scrollHeight,
width: document.body.scrollWidth
}
} else {
return {
height: document.documentElement.scrollHeight,
width: document.documentElement.scrollWidth
}
}
}
获取页面大小(宽高)
这里的页面大小是指body的大小,包括滚动区域,也用 getPageArea 方法获取,即scrollHeight和scollWidth属性
获取元素大小(宽高)
因为所有元素都有2个属性,用于取到它的宽和高( clientWidth,clientHeight, scrollWidth, scrollHeight),但有一个前提条件:被取值的元素没有滚动条。
如果要取宽高的元素有滚动条时,scrollWidth 和 scrollHeight 返回的是内部内容的总宽高,而clientWidth 和 clientHeight 总是返回该元素宽高,所以这里有两种情况,要取宽高的元素是否有滚动条?
有滚动条:
// js
function getElSizeByClient(el) {
return {
height: el.clientHeight,
width: el.clientWidth
}
}
没有滚动条:
// js
function getElSizeByClient(el) {
return {
height: el.clientHeight,
width: el.clientWidth
}
}
或
// js
function getElSizeByScroll(el) {
return {
height: el.scrollHeight,
width: el.scrollWidth
}
}
获取元素位置(上左)
因为页面基于视口左上角(0,0)定位,所以我们只能拿到上和左的值,右和下可以通过计算得出来, 使用这两个属性拿到顶部和左边的值
上左:
el.offsetTop;
el.offsetLeft;
上面的属性返回的是距离父元素的值,如果要拿到绝对距离,需进行层层遍历把值累加。
function getElementOffsetLeft(element) {
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while(current !== null) {
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementOffsetTop(element) {
var actualTop = element.offsetTop;
var current = element.offsetParent;
while(current !== null) {
actualTop += current.offsetTop,
current = current.offsetParent
}
return actualTop;
}