问题
通过点击一控件,在控件的下面显示一个浮动层,通常的做法是:获取此控件的offset值,再计算出浮动层的top,left等css属性的值,赋值即可。
那么下面就看一下如何获取控件的offset值。
纯JS的实现
首先想到的是这样的一段js。
document.getElementById(
"
divFloat
"
).style.top
=
document.getElementById(
"
Button
"
).offsetLeft
+
25
;
发现需要添加值单位,那么就修改成下面这样子。
document.getElementById(
"
divFloat
"
).style.top
=(
document.getElementById(
"
Button
"
).offsetLeft
+
25)+"px"
;
用IETester和FireFox再测试下,IE6+下都可以,如以前一样,写出的纯js的方法无情地被FireFox鄙视了,获取的值不正确。
网上再查了下,发现应该这样写,通过循环,层层向上计算,最后得到准确的offset值。
function
getOffsetLeft(o)
{
var left = 0 ;
var offsetParent = o;
while (offsetParent != null && offsetParent != document.body)
{
left += offsetParent.offsetLeft;
offsetParent = offsetParent.offsetParent;
}
return left;
}
{
var left = 0 ;
var offsetParent = o;
while (offsetParent != null && offsetParent != document.body)
{
left += offsetParent.offsetLeft;
offsetParent = offsetParent.offsetParent;
}
return left;
}
jQuery的实现
再细一步去查相关问题时发现jQuery中已经包含了实现此功能的函数:offset(),很好地兼容了各浏览器。
$(
"
#Button
"
).offset().left
还有一个函数是:position(),两者详细的对比分析在这里:深入剖析Jquery中的offset()和position()
下载源码后发现jQuery是这样实现的
jQuery.fn.extend({
position: function () {
if ( ! this [ 0 ] ) {
return null ;
}
var elem = this [ 0 ],
// Get *real* offsetParent
offsetParent = this .offsetParent(),
// Get correct offsets
offset = this .offset(),
parentOffset = / ^body|html$ / i.test(offsetParent[ 0 ].nodeName) ? { top: 0 , left: 0 } : offsetParent.offset();
// Subtract element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
offset.top -= parseFloat( jQuery.curCSS(elem, " marginTop " , true ) ) || 0 ;
offset.left -= parseFloat( jQuery.curCSS(elem, " marginLeft " , true ) ) || 0 ;
// Add offsetParent borders
parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[ 0 ], " borderTopWidth " , true ) ) || 0 ;
parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[ 0 ], " borderLeftWidth " , true ) ) || 0 ;
// Subtract the two offsets
return {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
};
},
offsetParent: function () {
return this .map( function () {
var offsetParent = this .offsetParent || document.body;
while ( offsetParent && ( ! / ^body|html$ / i.test(offsetParent.nodeName) && jQuery.css(offsetParent, " position " ) === " static " ) ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent;
});
}
});
position: function () {
if ( ! this [ 0 ] ) {
return null ;
}
var elem = this [ 0 ],
// Get *real* offsetParent
offsetParent = this .offsetParent(),
// Get correct offsets
offset = this .offset(),
parentOffset = / ^body|html$ / i.test(offsetParent[ 0 ].nodeName) ? { top: 0 , left: 0 } : offsetParent.offset();
// Subtract element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
offset.top -= parseFloat( jQuery.curCSS(elem, " marginTop " , true ) ) || 0 ;
offset.left -= parseFloat( jQuery.curCSS(elem, " marginLeft " , true ) ) || 0 ;
// Add offsetParent borders
parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[ 0 ], " borderTopWidth " , true ) ) || 0 ;
parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[ 0 ], " borderLeftWidth " , true ) ) || 0 ;
// Subtract the two offsets
return {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
};
},
offsetParent: function () {
return this .map( function () {
var offsetParent = this .offsetParent || document.body;
while ( offsetParent && ( ! / ^body|html$ / i.test(offsetParent.nodeName) && jQuery.css(offsetParent, " position " ) === " static " ) ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent;
});
}
});
没有太理解,先贴在这里了!
作者:Parry
出处:http://www.cnblogs.com/parry/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。