3
头图

在开发中经常用到获取元素位置和大小的需求,我最近在vue2.x上写了一个图片查看组件,它有拖动,定点缩放功能,这就需要获取视口大小,元素位置和大小。
看了阮老师的相关文章,实现了这个组件,也顺便在阮老师的这篇文章基础上整理一下,方便日后查阅。

获取视口大小(宽高)

任何元素都有 clientHeight 和 clientWidth 属性,也可用来获取视口大小。
image

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属性
image

获取元素大小(宽高)

image
因为所有元素都有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)定位,所以我们只能拿到上和左的值,右和下可以通过计算得出来, 使用这两个属性拿到顶部和左边的值
上左:

image

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;
}

welsen
32 声望1 粉丝

一般般先生