Skip to content

网页位置和大小(一) #23

@shiiiiiiji

Description

@shiiiiiiji

http://www.ruanyifeng.com/blog/2009/09/find_element_s_position_using_javascript.html

一、网页的大小和浏览器的大小
网页大小:一张网页的全部面积,就是它的大小。网页大小由内容和 CSS 样式决定
浏览器大小:在浏览器窗口看到的那部分网页面积,又叫做视口(viewport)

二、获取网页大小
网页上的每个元素,都有 clientHeight 和 clientWidth 属性。
这两个属性指元素的内容部分再加上 padding 所占据的视觉面积,不包括 border 和滚动条占用的空间。

image

由此,document.clientHeight 和 document.clientWidth 就代表了网页的大小(只读属性)。获取方式如下:

function getViewport() {
	if (document.compatMode == 'BackCompat') {    // 文档模式判断
		return {
			width: document.body.clientWidth,
			height: document.body.clientHeight
		};
	} else {
		return {
			width: document.documentElement.clientWidth,
			height: document.documentElement.clientHeight
		};
	}
}

三、另一种方式
网页中的每个元素,还都有 scrollHeight 和 scrollWidth 属性,包含滚动条在内的该元素的视觉面积。

function getPagearea() {
	if (document.compatMode == 'BackCompat') {
		return {
			width: document.body.scrollWidth,
			height: document.body.scrollHeight
		};
	} else {
		return {
			width: document.documentElement.scrollWidth,
			height: document.documentElement.scrollHeight
		};
	}
}

需要注意:
这个函数有一个问题。如果网页内容能够在浏览器窗口中全部显示,不出现滚动条,那么网页的clientWidth和scrollWidth应该相等。但是实际上,不同浏览器有不同的处理,这两个值未必相等。改写如下(取两者较大值):

function getPagearea(){
    if (document.compatMode == "BackCompat"){
      return {
        width: Math.max(document.body.scrollWidth,
                document.body.clientWidth),    // 取大值
        height: Math.max(document.body.scrollHeight,
                document.body.clientHeight)
      }
    } else {
      return {
        width: Math.max(document.documentElement.scrollWidth,
                document.documentElement.clientWidth),
        height: Math.max(document.documentElement.scrollHeight,
                document.documentElement.clientHeight)
      }
    }
  }

四、获取网页元素的绝对位置
绝对位置,指元素的左上角相对于整张网页左上角的坐标,通过计算获得。每个元素都有 offsetTop 和 offsetLeft 属性,表示该元素的左上角与父容器(offsetParent对象)左上角的距离,因此进行迭代累加,就可以得到该元素的绝对坐标。

注意,此方面不适用于 表格 和 iframe,因为在其中,offsetParent 对象未必等于父容器。

image

function getElementLeft(element) {
	var actualLeft = element.offsetLeft;
	var current = element.offsetParent;

	while (current !== null) {
		actualLeft += current.offsetLeft;
		current = current.offsetParent;
	}

	return actualLeft;
}

function getElementTop(element) {
	var actualTop = element.offsetTop;
	var current = element.offsetParent;

	while (current !== null) {
		actualTop += current.offsetTop;
		current = current.offsetParent;
	}

	return actualTop;
}

五、获取网页元素的相对位置
相对位置,指该元素左上角相对于浏览器窗口左上角的坐标。相对位置 = 绝对位置 - 页面的滚动条滚动的位置(document 对象的 scrollTop 属性和 scrollLeft 属性,可读写 => 自动滚动网页到相应位置)

image

function getElementViewLeft(element) {
	var actualLeft = element.offsetLeft;
	var current = element.offsetParent;

	while (current !== null) {
		actualLeft += current.offsetLeft;
		current = current.offsetParent;
	}

	if (document.compatMode == 'BackCompat') {
		var elementScrollLeft = document.body.scrollLeft;
	} else {
		var elementScrollLeft = document.documentElement.scrollLeft;
	}

	return actualLeft - elementScrollLeft;
}

function getElementViewTop(element) {
	var actualTop = element.offsetTop;
	var current = element.offsetParent;

	while (current !== null) {
		actualTop += current.offsetTop;
		current = current.offsetParent;
	}

	if (document.compatMode == 'BackCompat') {
		var elementScrollTop = document.body.scrollTop;
	} else {
		var elementScrollTop = document.documentElement.scrollTop;
	}

	return actualTop - elementScrollTop;
}

六、获取元素位置的快速方法
getBoundingClientRect() 方法,返回一个对象,包含 left、right、top、bottom 四个属性,分别对应该元素的左上角和右下角相对于浏览器窗口(viewport)左上角和右下角的距离。

所以,就是:

// 相对位置
var X= this.getBoundingClientRect().left;
var Y =this.getBoundingClientRect().top;

// 绝对位置
var X= this.getBoundingClientRect().left + document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top  +document.documentElement.scrollTop;

七、滚动
什么是滚动,滚动的原理?
全局滚动、局部滚动
滚动尺寸如何计算

八、pramper/Blog#10

题外话:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model
元素的 width 和 height 由盒模型决定,设置元素的 width 一般仅包括 content,但如果将其 box-sizing 属性{默认值为 content-box }设置为 border-box,那么 width 将包含 content, padding, border 部分

image

注意一些相关概念:
content-box、padding-box、border-box、margin-box
分别可由这些属性控制:
width/height
padding => padding-top/right/bottom/left
border => border-width
margin => margin-top/right/bottom/left

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions