取得位置
元素被定位在何处依赖于它的css参数以及与其邻接的内容而不同。访问CSS属性或计算后的实际值都没有提供的一个能力是,获取元素在页面中或者仅在其它元素中的确切位置。
首先,我们来看如何获取元素在页面中的位置。你拥有几个可支配的元素属性可用来找到这一信息。所有的现代浏览器都支持以下三个属性;当然它们各自是怎么处理的,又是另外一回事了:
offsetParent: 理论上,这是元素在其中定位的父级元素。但是在实际情况下,offsetParent
引用的元素取决于浏览器(比如说,在FireFox中,它引用根节点,而在Opera中,则是直接父元素。
offsetLeft和offsetTop: 这些参数是元素在其offsetParent 上下文中的水平和垂直偏移。在现代浏览器上,它总是精确的。现在,问题在于寻求一种可以跨浏览器工作的用来判定方式元素位置的一致的办法。实现这一点的最一致的办法如程序7-4所示:使用offsetParent 属性沿着DOM树上行,一路累加偏移值。
程序7-4. 计算元素相对于文档的x和y坐标的辅助函数
//计算元素的X(水平,左)位置
function pageX(elem) {
//检查我们是否已经到了根元素
return elem.offsetParent ?
//如果我们还能往上,则将当前偏移与向上递归的值相加
elem.offsetLeft + pageX( elem.offsetParent ) :
//否则,取当前偏移
elem.offsetLeft;
}
//计算元素的Y(垂直,顶)位置
function pageY(elem) {
//检查我们是否已经到了根元素
return elem.offsetParent ?
//如果我们还能往上,则将当前偏移与向上递归的值相加
elem.offsetTop + pageY( elem.offsetParent ) :
//否则,取当前偏移
elem.offsetTop;
}
定位问题的另一部分是计算元素在其父元素中的偏移。需要注意的重要的一点是,简单地使用元素的style.left 或style.top属性是不够的,因为你可能想要找出没有用Javascript或CSS定义样式的元素的位置。使用元素相对于其父元素的位置,你可以向DOM添加额外的相对该父元素定位的元素。比如,这个值用来建造上下文相关的工具提示是非常理想的。为了找到元素相对于其父元素的位置,你必须再一次求助于offsetParent 属性。因为该属性并不能保证返回特定元素的实际的父元素,你不得不使用你的pageX和pageY 函数来找到父元素与子元素之间的位置差异。在程序7-5所示的两个函数中,我试图首先使用offsetParent,如果它是当前元素的实际的父元素;否则,我将继续使用pageX 和pageY 方法沿DOM 上行,以确定它的实际位置。
程序7-5. 用来确定元素相对于其父元素位置两个函数
//查找元素在其父元素中的垂直位置
function parentX(elem) {
//如果offsetParent就是元素的parent,则提前返回
return elem.parentNode == elem.offsetParent ?
elem.offsetLeft :
//否则,我们需要找出两个元素相对整个页面的位置,计算差值
pageX( elem ) – pageX( elem.parentNode );
}
//查找元素在其父元素中的垂直位置
function parentY(elem) {
//如果offsetParent就是元素的parent,则提早返回
return elem.parentNode == elem.offsetParent ?
elem.offsetTop :
//否则,我们需要找出两个元素相对整个页面的位置,计算差值
pageY( elem ) – pageY( elem.parentNode );
}
定位问题的最后一方面是找出元素相对于其CSS容器的位置。如前面所讨论的,元素可能实际被包含在一个元素中而相对于另一个元素被定位(通过使用相对和绝对定位)。记住这一点,你可以回头利用getStyle 函数来得出计算后的CSS 偏移值,因为那正是等效的定位。有两个可用的简单的包装函数可以处理这一点,如程序7-6所示。它们都只是简单调用getStyle 函数,但同时也删除任何多余的(除非你不是使用基于像素的布局,它才是有用的)单位信息(比如说,100px将变成100)。
程序7-6. 找出元素的CSS定位的辅助函数
//得到元素的left位置
function posX(elem) {
//取得计算后样式并从中提取数字
return parseInt( getStyle( elem, “left” ) );
}
//得到元素的top位置
function posY(elem) {
//取得计算后的样式并从中提取数字
return parseInt( getStyle( elem, “top” ) );
}