您现在的位置: 365建站网 > 365学习 > 深入分析获取元素坐标的三种方法的不同地方

深入分析获取元素坐标的三种方法的不同地方

文章来源:365jz.com     点击数:279    更新时间:2009-09-19 10:25   参与评论
说坐标就要考虑参考点,首先要理解获取元素坐标是以文档(HTML元素)的左上角为参考点,不是浏览器左上角
案例分析
<div id="testid" style="border:solid 10px red; width:400px; height:200px; position:relative; overflow:auto; ">
   testid
  <div id="testid1" style="border:solid 5px green; position:absolute; width:200px; height:300px; top:70px; left:100px ">
   testid1
  </div>
</div>
<input type="button" value="点击案例1" onclick="eyejsTest('testid1')"  />
<input type="button" value="点击案例2" onclick="eyejsTest2('testid1')"  />
<input type="button" value="点击案例3" onclick="eyejsTest3('testid1')"  />
----------------------------------------
第一种方法eyejsGetNode1,是很常用的方法,可这种写法在某些情况下是不对的
  准确地说只能应用在该元素和所有的父级节点不能有边框和滚动,否则获取到的坐标就是不正确的
   必需准确地理解offsetTop和offsetLeft, 以offsetTop为例,offsetTop是本元素的外侧到直接父级的内侧的距离(如果有滚动部分,包括滚动部分)
 请看详解offsetTop,offsetLeft,offsetParent并给于案例
<script type="text/JavaScript">
function $(id){return document.getElementById(id);}
var eyejsGetNode1=function(id){
   var obj=$(id);
   var pos =[];
   pos =[obj.offsetLeft,obj.offsetTop];//
   var parent = obj.offsetParent;    
   while(parent){ 
       pos[0] += parent.offsetLeft;
       pos[1] += parent.offsetTop;
       parent=parent.offsetParent;
   } 
   return {x:pos[0],y:pos[1]};
}
var eyejsTest=function(id){
   var node=eyejsGetNode1(id);
    alert("Y坐标"+node.y);
}
</script>
点击弹出元素的坐标,再滚动后,再点击弹出元素的坐标
可以发现:该元素的已经发现变化坐标, 可计算结果并没有变化,(应该减去滚动部分)
<div style="margin-top:20px; border-top:solid 1px red; width:500px;">案例二</div>
<script type="text/javascript">
/*方法二:弥补方法一的缺点  加上边框部分和除去元素滚动部分,但不能除去body滚动部分*/
var $ = function (id) {return "string" == typeof id ? document.getElementById(id) : id;};
var isIE = (document.all) ? true : false;
if(!isIE){
    HTMLElement.prototype.__defineGetter__("currentStyle", function () {
        return this.ownerDocument.defaultView.getComputedStyle(this, null);
    });
}
var eyejsGetNode2=function(id){
   var obj=$(id);
   var x=0,y=0;
   var scrollX=0,scrollY=0;
   if(obj.offsetParent){
     if( obj.offsetParent.tagName.toLowerCase()!="body"&&obj.offsetParent.tagName.toLowerCase()!="html" ){
       scrollX=obj.offsetParent.scrollLeft;
       scrollY=obj.offsetParent.scrollTop;
       //去掉元素滚动部分,但是不能除掉html或body的滚动部分,理解obj.offsetParent的指向哪个元素,最顶级的父级元素是IE是HTMLhtmlElement而
       //FF是HTMLbodyElement 因此要这样判断
     }
   }
   x+=obj.offsetLeft-scrollX;
   y+=obj.offsetTop-scrollY;
   while(obj=obj.offsetParent){
      scrollX=0;scrollY=0;
      var borderLeftWidth=0;
      var borderTopWidth=0;
      if(obj.tagName.toLowerCase()!="body"||obj.tagName.toLowerCase()!="html"){
         borderLeftWidth=!isNaN(parseInt(obj.currentStyle.borderLeftWidth))?parseInt(obj.currentStyle.borderLeftWidth):0;
         borderTopWidth=!isNaN(parseInt(obj.currentStyle.borderTopWidth))?parseInt(obj.currentStyle.borderTopWidth):0;
      }
      if(obj.offsetParent){
         if( obj.offsetParent.tagName.toLowerCase()!="body"&&obj.offsetParent.tagName.toLowerCase()!="html" ){
           scrollX=obj.offsetParent.scrollLeft;
           scrollY=obj.offsetParent.scrollTop;
         }
      }
      //alert(obj.offsetParent);
      x+=obj.offsetLeft+borderLeftWidth-scrollX;
      y+=obj.offsetTop+borderTopWidth-scrollY;
      if(obj.tagName.toLowerCase()=="html")
        break;
   }
   return {"x":x,"y":y};
}
var eyejsTest2=function(id){
   var node=eyejsGetNode2(id);
   alert("Y坐标"+node.y);
}
</script>
<div>
点击弹出元素的坐标,再滚动后,再点击弹出元素的坐标
可以发现:该元素的已经发现变化坐标, 计算结果也着随变化
但是你如果先放在IE下测试,再放在FF测试你会发现结果不一样
为什么呢?去掉ID为testid的元素的边框样式,再试试,会发现结果一样了
<div>
</div>
----
案例三:
利用浏览器内置的获取元素坐标函数getBoundingClientRect
//此方法在IE和Firefox/3.0.12版本下通过
<script type="text/javascript">
var eyejsGetNode3=function(id){
   var el=$(id);
   var pos =[];
   var box=null;
   if(el.getBoundingClientRect){
      box = el.getBoundingClientRect();
      var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
        var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
        return {x:box.left + scrollLeft, y:box.top + scrollTop}; //
   }
   return {x:0,y:0};
}
var eyejsTest3=function(id){
   var node=eyejsGetNode3(id);
    alert("Y坐标"+node.y);
}
</script>
案例下载地址: http://www.eyejs.com/html/66/n-166.html

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (279人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------