JavaScript与CSS—元素的位置和各种坐标系
使⽤位置、尺⼨和可见性基本就可以在现代浏览器中模拟绝⼤多数常见的⽤户效果了。元素的位置是实现交互效果的基础。在CSS中,元素使⽤偏移量来定位,它是通过元素到它⽗元素的左上⾓的偏移量来计算。CSS的坐标系如下图
页⾯上的所有元素都有left(⽔平位置)和top(垂直位置)的偏移量。为了更好理解这⼀点,先了解⼀下CSS的定位⽅式。基础的HTML代码是:
<html>
<head>
<style>
p {
border: 3px solid red;
padding: 10px;
width: 400px;
background: #FFF;
}
p.odd {
/* 定位信息 */
position: static;
top: 0px;
left: 0px;
}
</style>
cssclass属性</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Etiam ...</p>
<p class='odd'>Phasellus dictum dignissim justo. Duis nec risus id nunc ...</p>
<p>Sed vel leo. Nulla iaculis, tortor non laoreet dictum, turpis diam ...</p>
</body>
</html>
通过对第⼆个段落的定位,分析⼀下CSS的定位⽅式。
□静态定位:这是默认⽅式。它遵循⽂档的普通流动(flow)。当静态定位中,top和left属性⽆效。下图的定位代码是 position:static; top:0px; left:0px; 的效果:
□相对定位:和静态定位类似,同样遵循⽂档的普通流动。如果设置了top和left属性则会产⽣相应的偏移。下图的定位代码是:position:relative; top:-50px; left:50px;
□绝对定位:绝对定位会使元素完全跳出页⾯布局的普通流动,会相对于它的第⼀个⾮静态定位的祖先元素⽽定位。如果没有这样的祖先元素,则相对于整个⽂档。下图的定位代码是:position:absolute; top:20px; left:0px;
□固定定位:固定定位相对于浏览器窗⼝⽽定位。设置top和left为0会使它在浏览器的左上⾓显⽰,⽽且不受滚动条的影响。下图的定位代码是:position:fixed; top:20px; right:0px;
元素的位置取决于CSS设置,同时⼜受其它因素的影响。所以单纯的访问CSS属性并不能获取元素的精确位置。为了获取元素相对于页⾯的位置,有⼀些CSS属性可以利⽤,在现代浏览器中都⽀持以下3个属性:
□ offsetParent : 理论上,这是元素的⽗元素,元素相对于它定位
□ offsetLeft 和 offfsetTop : 在 offsetParent 环境中的⽔平和垂直偏移量
为了获取元素相对于页⾯的精确位置,可以遍历DOM,使⽤offsetParent属性并累加它们的偏移量来计算元素的位置。下⾯是连个确定元素相对于整个⽂档的x 和y位置的辅助函数:
// 获取元素的⽔平位置
function pageX(elem) {
var p = 0;
// 累加每⼀个⽗元素的偏移量
while ( elem.offsetParent ) {
// 增加偏移量
p += elem.offsetLeft;
// 遍历下⼀个⽗元素
elem = elem.offsetParent;
}
return p;
}
/
/ 获取元素的垂直位置
function pageY(elem) {
var p = 0;
// 累加每⼀个⽗元素的偏移量
while ( elem.offsetParent ) {
// 增加偏移量
p += elem.offsetTop;
// 遍历下⼀个⽗元素
elem = elem.offsetParent;
}
return p;
}
接下来是获取元素相对于它的⽗元素的⽔品和垂直位置。简单地使⽤ style.left 或 p 并不够,因为需要处理的元素可能尚未经过JavaScript或CSS的格式化。要到元素相对于它的⽗元素的位置,可以利⽤offsetParent属性,但该属性并不保证能够反追指定元素的真实⽗元素,所以还需要使⽤前⾯的pageX和pageY函数来计算⽗元素和⼦元素之间的差。在下⾯的函数中,如果是当前元素的⽗元素,则使⽤offsetParent;否则继续遍历DOM,使⽤pageX和pageY函数来确定它的真实位置。
// 获取相对于⽗元素的⽔平位置
function parentX(elem) {
// 如果 offsetParent 是元素的⽗元素,则返回
return elem.parentNode == elem.offsetParent ?
elem.offsetLeft :
// 否则计算元素和其⽗元素的⽔平差值
pageX( elem ) - pageX( elem.parentNode );
}
// 获取相对于⽗元素的垂直位置
function parentY(elem) {
// 如果 offsetParent 是元素的⽗元素,则返回
return elem.parentNode == elem.offsetParent ?
elem.offsetTop :
// 否则计算元素和其⽗元素的⽔平差值
pageY( elem ) - pageY( elem.parentNode );
}
最后是获取元素相对于它的CSS容器的位置。在CSS定位⽅式的讨论中我么知道,即使元素包含在另⼀个元素内,它也可以相对于其他的⽗元素定位(使⽤相对和绝对定位)。这种情形可以使⽤getStyle函数得到CSS偏移的最终值,这等于元素的位置值。
// 左侧位置
function posX(elem) {
// 获取样式并得到数值
return parseInt( getStyle( elem, "left" ) );
}
// 顶端位置
function posY(elem) {
// 获取样式并得到数值
return parseInt( getStyle( elem, "top" ) );
}
设置位置
调整元素位置的唯⼀⽅法就是修改它的CSS属性,仅需要修改left和top属性即可(尽管还有right和bottom属性)。这样就可以设置元素的位置,不管元素的当前位置在哪⼉⾥。
// 设置元素的⽔平位置
function setX(elem, pos) {
// 设置CSS的 'left' 属性
elem.style.left = pos + "px";
}
// 设置元素的垂直位置
function setY(elem, pos) {
// 设置CSS的 'top' 属性
p = pos + "px";
}
最后,实现⼀对函数⽤来增加相对于当前位置的偏移量。利⽤这个函数可以调整元素的位置向上偏移5像素,从⽽实现各种动画效果。
// 增加⽔平偏移量
function addX(elem,pos) {
setX( posX(elem) + pos );
}
// 增加垂直偏移量
function addY(elem,pos) {
setY( posY(elem) + pos );
}
===============================================坐标系⽂⼀=================================
在JavaScript中有三种不同的坐标系:屏幕坐标,窗⼝(viewport)坐标和⽂档(document)坐标。其中要注意的是⽂档坐标和窗⼝坐标的关系。窗⼝坐标的原点是其视⼝的作上⾓,由于窗⼝具有滚动条,⽂档的坐标原点可能会滚动到窗⼝以外,这时要注意两者的关系。在代码的书写过程中要注意的是JavaScript的AIP返回的值是基于什么坐标系的。在利⽤javaScript来操纵css style的时候中的时候absolute的坐标是相对于document坐标系的。
以下是⼀些常见的坐标问题
1.document中elemenet的位置和⼤⼩
每个element都有四个属性:offsetleft,offsetTop,OffsetHeight,offsetWidth,这四个属性分别代表的是element的左上⾓和⾼宽。
最初是由IE4引⼊的,后来也得到了其他浏览器的⽀持。但是这些属性值相对于该element的offsetParent的坐标.在<html>⽂件中中<body>的offsetParent为null,因此要得到⼀个elment的坐标的正确⽅法是
getElementX(e)
{
var x=0;
while(e)
{
x+=e.offsetLeft;
e=e.offsetParent;
}
return x;
}
这个⽅法的返回值是相对于document的坐标的,它不会受到窗⼝是否滚动的影响。
但是这种⽅法还有⼀个⼩问题,那就是⼀个element通过设置它的css属性overflow可以拥有⾃⾝的滚动条,这时以这种⽅法得到的只是不正确的。这时正确的⽅法如下
function getY(element)
{
// Iterate the offsetParents
// Add up offsetTop values
var y = 0;
for(var e = element; e; e = e.offsetParent)
y += e.offsetTop;
// Now loop up through the ancestors of the element, looking for
// any that have scrollTop set. Subtract these scrolling values from
// the total offset. However, we must be sure to stop the loop before
// we reach document.body, or we'll take document scrolling into account
// and end up converting our offset to window coordinates.
for(e = element.parentNode; e && e != document.body; e = e.parentNode)
// subtract scrollbar values
if (e.scrollTop) y -= e.scrollTop;
// This is the Y coordinate with document-internal scrolling accounted for.
return y;
}
2.⿏标事件中的坐标问题
在DOM2的时间模型中的MouseEvent对象和IE的时间模型中的Event对象都有⼀对属性clinetX和clientY属性,它们表明的是⿏标事件发⽣时⿏标在viewport坐标中的位置,他们都没有考虑doucument的滚动。如果要得到docuemnt做坐标系下的位置,则应加上windows.pageOffsetX和windows.pageOffsetY的值.
====================================坐标系⽂⼆========================================
Window Geometry
窗⼝⼏何关系
引⽤
Screen coordinates describe the position of a browser window on the desktop; they are measured relative to the upper-left corner of the desktop.
Screen坐标系是描述浏览器窗⼝和桌⾯之间的⼏何关系的,其坐标是相对于桌⾯左上⾓的。
引⽤
Window coordinates describe a position within the web browser's viewport; they are measured relative to the upper-left corner of the viewport.
Window坐标系描述了浏览器页⾯可视区域的⼏何关系,其坐标是相对于可视区域的左上⾓。
引⽤
Document coordinates describe a position within an HTML document; they are measured relative to t
he upper-left corner of the document. When the document is longer or wider than the viewport (as web pages often are), document coordinates and window coordinates are not the same, and you'll need to take the position of the scrollbars into account when converting between these two coordinate systems.
Document坐标系描述了HTML元素与document⽂档的⼏何关系,其坐标是相对于document对象的左上⾓的。
当document⾜够长⽽产⽣滚动条,document坐标系和window坐标系就会产⽣差异,两个坐标系之间就要考虑转换的⽅法。
引⽤
For some reason, IE places these window geometry properties on the <body> of the HTML document. And, further confusing matters, IE 6, when displaying a document with a <!DOCTYPE> declaration, places the properties on the document.documentElement element instead of document.body.
IE在默认状态下将这些相关属性放在document.body下,但如果有<!DOCTYPE>声明,那么就会放在document.documentElement下。
浏览器window对象坐标⼤⼩可视区域⼤⼩滚动条document对象坐标⼤⼩
FF screenX/Y innerWidth/Height pageXOffset/YOffset documentElement.scrollLeft/Top IE with doctype screenLeft/Top documentElement.clientWidth documentElement.scrollLeft/Top/Height documentElement.scrollLeft/Top
以下是⼀个获取⼏何参数的函数
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论