这两天在写瀑布流的实现,使用了一些关于获取文档坐标、元素位置的函数,刚好看到犀牛书上关于这部分的介绍,特写此文章进行总结,方便日后查找使用。
文档坐标和视口坐标
元素的位置X,Y坐标是相对于文档的左上角或视口的左上角。向右表示X增加,向下表示Y增加,以像素来度量。
首先需要明确的是,文档坐标不等于视口坐标。“视口”只是实际显示文档内容的浏览器的一部分,不包括浏览器的菜单、工具条、标签页等“外壳部分”。对于框架页中显示的文档,视口是指定义了框架也的<iframe>元素。
一般而言,文档坐标 = 视口坐标 +/- 滚动的偏移量
浏览器窗口的滚动条位置
window.pageXOffset,window.pageYOffset
scrollLeft, scrollTop
正常情况,可以通过document.documentElement来获取
怪异模式,必须使用document.body来获取
function getScrollOffset(w){
w = w || window;
if(w.pageXOffset != null)
return { x: w.pageXOffset, y: w.pageYOffset };
var d = document;
//标准模式
if(document.compatMode == "CSS1Compat")
return { x: d.documentElement.scrollLeft, y:d.documentElement.scrollTop };
//怪异模式
return { x: d.body.scrollLeft, y: d.body.scrollTop };
}
视口尺寸
function getViewportSize(w){
//使用指定窗口,如果不带参数则使用当前窗口
w = w || window;
if(w.innerWidth != null)
return { w: w.innerWidth, h: w.innerHeight };
var d = w.document;
//标准模式
if(document.compatMode == "CSS1Compat")
return { w: d.documentElement.clientWidth,
h: d.cocumentElement.clientHeight };
//怪异模式
return { w: d.body.clientWidth, h: d.body.clientHeight }
}
查询元素的尺寸和位置
调用该元素的getBoundingClientRect(),返回的是一个有left,right,top,bottom属性的对象。left,top表示左上角的X,Y,right,bottom表示右下角的X,Y坐标。
返回的是在视口坐标中的位置。返回的坐标包括元素的边框和内边距,不包括外边距。
【注意】getBoundingClientRect并不是实时更新,只是调用方法时文档视觉状态的静态快照,在用户滚动或改变浏览器大小时不会更新它们。
//例如我想知道写文章的这个页面中“定时发布”的按钮的尺寸和位置
var box = document.getElementById("setPublishTime").getBoundingClientRect();
//ClientRect {top: 425, right: 1223, bottom: 460, left: 1141, width: 82, height : 35}
//获取宽度,高度的另一种方式
var w = box.width || (box.right - box.left);
var h = box.height || (box.bottom - box.top);
ps.对于内联元素调用getBoundingClientRect(),返回的是“边界矩形”,因为内联元素可能跨了多行,所以可能是由多个矩形组成的。对于分为两行的内联元素,边界矩形就包含了两行的宽度。如果需要查询内联元素每个独立的矩形,调用getClientRects()来获取一个只读的类对象数组。
获取某个坐标点的元素
如果想知道在视口的指定位置上有什么元素,使用document.elementFromPoint(x,y)
【注意】是视口坐标,而不是文档坐标。返回在指定位置的一个元素
典型案例:将鼠标指针的坐标传递给它来判断鼠标在哪个元素上。不过,鼠标事件对象的target属性已经包含了这些信息。故很少使用document.elementFromPoint()