最近公司业务需要,不得不提前原来的计划,提前开始研究无框架的Javascript动画。不使用任何框架,就算实现一个简单的slide和fide都需要大费周章,但感觉乐在其中,毕竟曾经接触过flash开发。
跟flash一样,动画的原理就是由一帧一帧静态画面连贯组成的貌似动态效果,其实放慢足够的倍数,就一张张静态画面。看过胶片式电影的朋友都明白,只要每秒超过24帧,而其间的间隔人眼难以觉察到。关于动画原理,这里就不加赘述了。
想把元素框移动起来,首先要找到元素框的位置,也就是元素框在页面的坐标,不同的参照物有不同的坐标位置。先来普及几个基本概念吧!
offsetWidth | clientWidth | scrollWidth |
offsetHeight | clientHeight | scrollHeight |
offsetLeft | clientLeft | scrollLeft |
offsetTop | clientTop | scrollTop |
1. clientHeight和clientWidth用于描述元素内尺寸,是指 元素内容 + 内边距 大小,不包括边框(IE下实际包括)、外边距、滚动条部分
2. offsetHeight和offsetWidth用于描述元素外尺寸,是指 元素内容 + 内边距 + 边框,不包括外边距和滚动条部分
3. clientTop和clientLeft返回内边距的边缘和边框的外边缘之间的水平和垂直距离,也就是左,上边框宽度
4. offsetTop和offsetLeft表示该元素的左上角(边框外边缘)与已定位的父容器(offsetParent对象)左上角的距离
5. offsetParent对象是指元素最近的定位(relative,absolute)祖先元素,递归上溯,如果没有祖先元素是定位的话,会返回null
视口(viewport):the visible portion of the canvas,也就是能看的见网页内容的页面部分。
页面:相比视口还包含了不可见的网页内容部分,例如出现滚动条,页面会有部分隐藏起来,在视口下面不可见,但页面内容确确实实存在。
获取页面的高度和宽度
网页中每个元素都有clientWidth和clientHeight属性,这两个属性是指内容部分加上padding部分,不包含border以及滚动条空间,更加不包括margin部分。因此,document元素的clientWidth和clientHeight就对应页面的宽度和高度。
获取网页宽度和高度的函数:
function getPageSize(){
if(document.compatMode == "BackCompat"){
return {
document.body.clientWidth,
height: document.body.clientHeight
}
}else{
return{
document.documentElement.clientWidth,
height: document.documentElement.clientHeight
}
}
}
另外需要注意的是,clientWidth和clientHeight都是只读属性,不能对它们赋值。网页上的每个元素还有scrollHeight和scrollWidth属性,指包含滚动条在内的该元素的视觉面积。那么,document对象的scrollHeight和scrollWidth属性就是网页的大小,换句话说,就是scrollbar滚动能看到的所有内容的长度和宽度。
如果网页内容能够在浏览器窗口中全部显示,不出现滚动条,那么理论上网页的clientWidth和scrollWidth应该相等。但是实际上,不同浏览器有不同的处理,这两个值未必相等。所以,我们需要取它们之中较大的那个值,因而可以使用Math.max()方法进行取值。
function getPageSizeToo(){
if (document.compatMode == "BackCompat"){
return {
Math.max(document.body.scrollWidth,
document.body.clientWidth),
height: Math.max(document.body.scrollHeight,
document.body.clientHeight)
}
} else {
return {
Math.max(document.documentElement.scrollWidth,
document.documentElement.clientWidth),
height: Math.max(document.documentElement.scrollHeight,
document.documentElement.clientHeight)
}
}
}
获取元素的绝对位置
元素的绝对位置,也即是相对于整个网页左上角的坐标,也是说是相对网页原点的坐标。元素属性里面没有坐标的现成值,需要通过offsetTop和offsetLeft属性计算得出。这两个属性分别表示左上角与父容器(offsetParent)左上角的距离。因而,元素的坐标Y就等于元素的offsetTop与祖先容器(无此概念)的offsetTop值得叠加。
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
以上函数对表格和iframe不适用,因为它们的offsetParent对象未必就是父容器。
获取元素相对位置
这个相对位置是相对于浏览器窗口的左上角,不是相对于整个页面的左上角。有了绝对位置以后,获得相对位置就很容易了,只要将绝对坐标减去页面的滚动条滚动的距离就可以了。滚动条滚动的垂直距离,是document对象的scrollTop属性;滚动条滚动的水平距离是document对象的scrollLeft属性。
function getElementViewLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
var elementScrollLeft = document.compatMode == "BackCompat" ? document.body.scrollLeft : document.documentElement.scrollLeft;
return actualLeft-elementScrollLeft;
}
function getElementViewTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
}
var elementScrollTop = document.compatMode == "BackCompat" ? document.body.scrollTop : document.documentElement.scrollTop;
return actualTop-elementScrollTop;
}
scrollTop和scrollLeft属性是可以赋值的,并且会立即自动滚动网页到相应位置,因此可以利用它们改变网页元素的相对位置。另外,element.scrollIntoView()方法也有类似作用,可以使网页元素出现在浏览器窗口的左上角。除了上面的函数以外,还有一种快速方法,可以立刻获得网页元素的位置。那就是使用getBoundingClientRect()方法。它返回一个对象,其中包含了left、right、top、bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左上角的距离。
所以,网页元素的相对位置就是
var X= this.getBoundingClientRect().left;
var Y =this.getBoundingClientRect().top;
再加上滚动距离,就可以得到绝对位置
var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;
目前,IE、Firefox 3.0+、Opera 9.5+都支持该方法,而Firefox 2.x、Safari、Chrome、Konqueror不支持。
(注明:大部分摘抄自http://www.ruanyifeng.com/blog/2009/09/find_element_s_position_using_javascript.html)