代码改变世界

javascript动画系列之 —— 获取坐标

2013-04-12 16:45  MoltBoy  阅读(652)  评论(2编辑  收藏  举报

  最近公司业务需要,不得不提前原来的计划,提前开始研究无框架的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

firefox布局截图

  视口(viewport):the visible portion of the canvas,也就是能看的见网页内容的页面部分。

  页面:相比视口还包含了不可见的网页内容部分,例如出现滚动条,页面会有部分隐藏起来,在视口下面不可见,但页面内容确确实实存在。

  获取页面的高度和宽度

  网页中每个元素都有clientWidth和clientHeight属性,这两个属性是指内容部分加上padding部分,不包含border以及滚动条空间,更加不包括margin部分。因此,document元素的clientWidth和clientHeight就对应页面的宽度和高度。

  获取网页宽度和高度的函数:

function getPageSize(){
    if(document.compatMode == "BackCompat"){
        return {
            width: document.body.clientWidth,
            height: document.body.clientHeight
        }
    }else{
        return{
            width: 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 {
        width: Math.max(document.body.scrollWidth,
                document.body.clientWidth),
        height: Math.max(document.body.scrollHeight,
                document.body.clientHeight)
      }
    } else {
      return {
        width: 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)