首先,我们知道用js计算一个元素的页面坐标的方法是:
(页面坐标是指元素相对于文档的坐标)
function getElementPosition(elem){
var elemTop = elem.offsetTop;//获得elem元素距相对定位的父元素的top
var elemLeft = elem.offsetLeft;
elem = elem.offsetParent;//将elem换成起相对定位的父元素
while(elem!=null){//只要还有相对定位的父元素
elemTop +=elem.offsetTop;//获得父元素 距他父元素的top值,累加到结果中
elemLeft += elem.offsetLeft;
elem = elem.offsetParent;//再次将elem换成他相对定位的父元素上;
}
return {
elemTop: elemTop,
elemLeft: elemLeft
};
}
将这个元素的offsetLeft和offsetTop与其offsetParent的相同属性相加,如此循环回溯直至根元素,
就可以得到元素在相对页面的上偏移量和左偏移量。
IE、Firefox 3+、Safari 4+、Opra 9.5 及 Chrome 为每个元素提供了一个getBoundingClientRect()方法。
这个方法会返回一个矩形对象,用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。
left属性和top属性大致等同于前面定义的getElementPosition(elem)的返回值的elemLeft属性和elemTop属性。
在ie7及ie7以下的html元素坐标会从(2, 2)开始算起,在ie8已经修复了这个bug。这就是多出两个像素的原因
jquery中,offset()函数用于设置或返回当前匹配元素相对于当前文档的偏移量,也就是相对于当前文档的坐标。
源码内部就是借用了getBoundingClientRect()方法。
jQuery.fn.extend({
offset: function( options ) {
if ( arguments.length ) {
return options === undefined ?
this :
this.each(function( i ) {
jQuery.offset.setOffset( this, options, i );
});
}
var docElem, win,
box = { top: 0, left: 0 },
elem = this[ 0 ],
doc = elem && elem.ownerDocument;
if ( !doc ) {
return;
}
docElem = doc.documentElement;
// Make sure it's not a disconnected DOM node
if ( !jQuery.contains( docElem, elem ) ) {
return box;
}
// If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
},
.........................
})