视口坐标,文档坐标
视口(viewport):也叫窗口坐标,实际显示文档内容的浏览器的部分,不包括浏览器外壳(菜单工具等),对于框架页中显示的文档,视口是定义框架页的<iframe>。
当文档比视口小时(无滚动),文档的左上角就是视口的左上角,文档坐标和视口坐标就相等。
文档坐标 = 视口坐标 + 滚动的偏移量。文档坐标本身不会随滚动发生变化。
Window对象的pageXoffset和pageYOffset在所有浏览器中均可获取滚动条的位置,除了IE8和以前更在的版本。
或者,IE(和所有现代浏览器)也可以通过scrollLeft 和scrollTop来获取滚动条的位置。重点来了:一般正常情况下通过查询文档的根节点(document.documentElement)来获取这些值,但在怪异模式下必须在文档的<body>元素上查询它们(document.body),
查询滚动条的位置:
function getScrollOffsets(w){ //使用指定的窗口,如果不带参数则使用当前窗口 w = w || window; //除了ie8及3更早的版本外,都可以使用 if(w.pageXoffset != null) return { x:w.pageXoffset, y:w.pageXoffset }; //对标准模式下的ie(或者任何浏览器) var d = w.document; if(document.compatMode == "CSS1Compat") return {x:d.documentElement.scrollLeft, y:d.documentElement.scrollTop}; //对怪异模式下的浏览器 return {x:d.body.scrollLeft, y:d.body.scrollTop}; }
如何检测文档以哪种模式渲染?
document.compatMode属性,if(document.compatMode == "CSS1Compat")就是标准模式,如果是BackCompat(或undefined),则是怪异模式。
获取元素的几何尺寸
查询元素尺寸的位置的最简单的方法:getBoundingClientRect(),该方法返回一个包含left,right,top,bottom属性的对象。left,top是左上角的x.y坐标,right, bottom是右下角的x,y坐标。这方法返回的是在视口中的位置。
将视口坐标转化为文档坐标:
var box = e.getBoundingClientRect(); var offsets = getScrollOffsets(); var x = box.left + offsets.x; var y = box.top + offsets.y;
该函数返回的坐标包含border和padding,但不包括margin。
getClientRect()和getBoundingClientRect()类似,二者的不同在于:被折断的两行斜体文本,使用getBoundingClientRect()会返回边界矩形,整个两行的宽度。
而getClientRect()可以查询内联元素每个独立的矩形。
注意:这些方法不是实时的,不会随着滚动而自动更新数据。像getElementById()这样的方法是实时的,文档变化时会自动更新。
刚才是判定在视口中元素在什么位置,还有一个方法可以判定在什么位置上有什么元素。Document对象的elementFromPoint()方法判定什么位置上有什么元素(这方法不常用)。指定的点在视口外,则该方法返回null。
滚动
Window 对象的scrollTop()方法接受一个点的XY坐标(文档坐标),并作为滚动量的偏移设置它们,即窗口滚动到指定的点出现在视口的左上角。
var documentHeight = document.documentElement.offsetHeight; var viewportHeight = window.innerHeight; window.scrollTo(0, documentHeight - viewportHeight);
每个HTML元素都会有如下属性:
offsetWidth | clientWidth | scrollWidth |
offsetHeight | clientHeight | scrollHeight |
offetLeft | clientLeft | scrollLeft |
offsetTop | clientTop | scrollTop |
offsetParent |
分别看一下这些属性吧:
- offsetWidth和offsetHeight返回元素的屏幕尺寸,包括:内容和 border 和 padding,,但不包括margin。即:offsetWidth = content + padding + border;
- offsetLeft 和 offsetTop 返回的是元素的XY坐标,通常来说,这些值是文档坐标,直接指定元素的位置。但如果该元素是已定位的元素的后代元素和一些其他元素(如表格单元),返回的坐标则是相对于祖先元素,而非文档,offsetParent属性指定这些属性的父元素。如果offseParent为null,则这些属性都是文档坐标。
- clientWidth 和clientHeight 包含内容和padding,不包含border。即:clientWidth = content + padding; 如果浏览器在padding和border之间添加了滚动条,clientWidth在其返回值中也不包含滚动条。
注意:对于<i><span>之类的内联元素,clientWidth 总是返回0。
- clientLeft 和clientHeight返回的是元素内边距的外边缘和他的边框的外边缘之间的水平距离和垂直距离,,,其实就是border。对于内联元素,clientLeft和clientTop总是0;
- scrollWidth 和scrollHeight = 内容 + padding + 溢出内容的尺寸,所以应大于clientWidth。 没有溢出时,scrollWidth 等于 clientWidth。
- scrollTop 和scrollLeft指定元素的滚动条位置。属性是可写的。
下面看一个例子,
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <div id="divParent" style="padding: 8px; background-color: #aaa; position: relative;"> <div id="divDisplay" style="background-color: #0f0; margin: 30px; padding: 10px; height: 300px; 200px; border: solid 3px #f00;"> </div> </div> <script type="text/javascript"> var div = document.getElementById("divDisplay"); var clientHeight = div.clientHeight; var clientWidth = div.clientWidth; div.innerHTML += "clientHeight:" + clientHeight + "<br>"; div.innerHTML += "clientWidth:" + clientWidth + "<br>"; var clientLeft = div.clientLeft; var clientTop = div.clientTop; div.innerHTML += "clientLeft:" + clientLeft + "<br>"; div.innerHTML += "clientTop:" + clientTop + "<br>"; var offsetHeight = div.offsetHeight; var offsetWidth = div.offsetWidth; div.innerHTML += "offsetHeight:" + offsetHeight + "<br>"; div.innerHTML += "offsetWidth:" + offsetWidth + "<br>"; var offsetLeft = div.offsetLeft; var offsetTop = div.offsetTop; div.innerHTML += "offsetLeft:" + offsetLeft + "<br>"; div.innerHTML += "offsetTop:" + offsetTop + "<br>"; var offsetParent = div.offsetParent; div.innerHTML += "offsetParent:" + offsetParent + "<br>"; var scrollWidth = div.scrollWidth; var scrollHeight = div.scrollHeight; div.innerHTML += "scrollWidth:" + scrollWidth + "<br>"; div.innerHTML += "scrollHeight:" + scrollHeight + "<br>"; var scrollLeft = div.scrollLeft; var scrollTop = div.scrollTop; div.innerHTML += "scrollLeft:" + scrollLeft + "<br>"; div.innerHTML += "scrollTop:" + scrollTop + "<br>"; </script> </body> </html>
可以根据上面的说明,做一下数学计算,得出各项值。
以上内容来自javascript权威指南(犀牛书),这里也附一个前辈的链接,它之前也写过一样的博客。估计也是看到犀牛书吧。http://www.cnblogs.com/dolphinX/archive/2012/11/19/2777756.html