关于offsetLeft与position:relative,margin:auto;的一些关系

2024-05-13 14:48

本文主要是介绍关于offsetLeft与position:relative,margin:auto;的一些关系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对于div的offsetLeft或offsetTop属性,它与postion的关系十分密切。


默认情况下是position:static;在position为static(即没有设置positoin属性,或position为空时)。

1.在ie7(ie6没有环境测试估计一样)中,div的offsetLeft的值是当前div左边框到它父级div左内边框的像素距离,对于它的父级div的position对它的结果没有影响。

2.在ie8,ie9,firefox,chorme中,祖先级的position对这个结果的影响是明显的,因为div的offsetLeft的值是当前div左边框到它祖先级中第一个带position:relative;或position:absolute属性的元素的像素距离。

以下代码在ie7,ie8,ie9,firefox,chrome下证明了这一点

<body style="margin:0px;">

<div style="margin-left:30px; margin-top:50px; width:300px; height:300px; background-color:#330000; position:absolute;" οnclick="alert('2:'+this.offsetLeft);">

<div style="margin-left:30px; margin-top:50px; width:200px; height:200px; background-color:#333300;" οnclick="alert('1:'+this.offsetLeft);">

<div style="margin-left:30px; margin-top:50px; width:100px; height:100px; background-color:#ff0000;" οnclick="alert('0:'+this.offsetLeft);"></div>

</div>

</div>

</body>



postion:relative(或absolute)来时,ie7,ie8,ie9,firefox,chrome下的表示是一致的。

position:relative;的div的offsetLeft的取值,与其祖先级div的postion值密切相关。如果position:relative;的div的祖先div都是postion:static;的话,那么这个div的offsetLeft的值就是当前div左边框到body的像素距离了,如果祖先div中有postion:relative;或position:absolute;的div,则当前div的offsetLeft的值就是当前div左边框到距离当前div最近的带有postion:relative;或position:absolute的祖先的像素距离。



在margin不为auto时

当margin为auto时,ie7和ie8,ie9,firefox,chrome表现出来的结果是很不一样的。以下是我的测试代码一:

<body style="margin:0px;">

<div style="margin:auto; width:300px; height:300px; background-color:#330000;" οnclick="alert(this.offsetLeft);">

<div style="margin:auto; width:200px; height:200px; background-color:#333300;" οnclick="alert(this.offsetLeft);">

<div style="margin:auto; width:100px; height:100px; background-color:#ff0000; position:relative;" οnclick="alert(this.offsetLeft);"></div>

</div>

</div>

</body>

此时在ie7上的表现跟我最开始的描述是一致的,就是说margin对ie的offsetLeft是没有任何影响的。但是在ie8,ie9,firefox,chrome下的表现就奇怪了。点击最里层的div,弹出的数依次是670,620,570这说明了加了margin:auto;后div的offsetLeft的取值直接就是当前div到body的距离。事实真是所有的带margin:auto的div的offsetLeft都是以body为参照取值吗?我觉得不可能,于是又改了代码,如下:

<body style="margin:0px;">

<div style="margin:auto; width:300px; height:300px; background-color:#330000;" οnclick="alert(this.offsetLeft);">

<div style="margin:auto; width:200px; height:200px; background-color:#333300; position:relative;" οnclick="alert(this.offsetLeft);">

<div style="margin:auto; width:100px; height:100px; background-color:#ff0000;" οnclick="alert(this.offsetLeft);"></div>

</div>

</div>

</body>

再点击最里层的div,弹出的数依次是

50,620,570

这里的表现直接就说明了ie8,ie9,firefox,chrome下,加了margin:auto;的div的offsetLeft的取值与position:relative的取值是一样的,但是加了margin:auto;的div不等于于position:relative的div,一个重要的依据是带position:relative的div(或是margin:auto;)在实际计算中不把margin:auto;的祖先当做计值参照。所以这里在记忆上可能会造成混乱。

总结:带margin:auto的div在计算offsetLeft时与position:relative是一样的,但是被计算是不按postion:relative看待,以实际position为准。

这个原因可能会造成ie8,ie9,firefox,chrome不能定位。

关于margin:auto;ie8,ie9,firefox,chrome下的再补充,上面的例子还不够说明margin:auto在ie8,ie9,firefox,chrome下的一些特殊性,

以下是新测试代码一:

<body style="margin:0px;">

<div id="d1" style="margin:auto; width:300px; height:300px; background-color:#330000;" οnclick="alert(this.offsetLeft);">

<div id="d2" style="width:250px; height:250px; background-color:#003333; margin-left:15px;" οnclick="alert(this.offsetLeft);">

<div id="d3" style="margin:auto; width:200px; height:200px; background-color:#333300;" οnclick="alert(this.offsetLeft);">

<div id="d4" style="width:100px; height:100px; background-color:#ff0000; margin-left:10px;" οnclick="alert(this.offsetLeft);"></div>

</div>

</div>

</div>

</body>

点击d4后依次弹出的数值是:620,610,585,570

这里是让我产生margin:auto在ie8,ie9,firefox,chrome下对offsetLeft的影响不止于以上所说的例子。照理说d4应该是10而不应该是620,但是它是620,说明ie8,ie9,firefox,chrome对margin:auto;div的子孙级div也是有特殊处理的。于是改变代码如下,新测试代码二:

<div id="d1" style="margin:auto; width:300px; height:300px; background-color:#330000;" οnclick="alert(this.offsetLeft);">

<div id="d2" style="width:250px; height:250px; background-color:#003333; margin-left:15px; position:relative;" οnclick="alert(this.offsetLeft);">

<div id="d3" style="margin:auto; width:200px; height:200px; background-color:#333300;" οnclick="alert(this.offsetLeft);">

<div id="d4" style="width:100px; height:100px; background-color:#ff0000; margin-left:10px;" οnclick="alert(this.offsetLeft);"></div>

</div>

</div>

</div>

点击d4后依次弹出的数值是:35,25,585,570

d4把带有属性position:relative的d2,当做offsetLeft的参照做计算了。

于是,反复更改代码测试,最后得出一个更完善的结论:

ie8,ie9,firefox,chrome下,带margin:auto的div在计算offsetLeft时与position:relative是一样的,但是被计算是不按postion:relative看待,以实际position为准;并且margin:auto;的div的子孙div都有如上相同的特性(其实就是继承);

以上的论述,会造成ie8,ie9,firefox,chrome下计算定位的难度,以下是我写的用于定位的js:


function L_getpos(obj)
{
 var left=0;
 var top=0;
 var oleft=obj.offsetLeft;
 var otop=obj.offsetTop;//oleft,otop原点坐标
 var rleft=0;
 var rtop=0;//position:relative的祖先元素的offsetLeft和offsetTop的累计和
 var relative=false;//与position相关,如果遇到父级的属性为relative或absolute时,此属性为true,为true之后的left和top取值,只取position为relative或absolute的div的offsetLeft和offsetTop
 var marginAuto=false;//祖先级中有没有margin:auto的属性,ie8,ie9,firefox,chrome是重要的判断
 var parentNode=obj;
 do{
  if(getCss(parentNode,"position")=="relative" || getCss(parentNode,"position")=="absolute")
  {
   relative=true;
  }
  if((getCss(parentNode,"margin")).indexOf("auto")>=0)
  {//这里有个bug,firefox下如果把margin属性写在css文件中的话,没有办法获取这个属性,会造成计算结果不准
   marginAuto=true;
  }else{//chrome的兼容
   if(getCss(parentNode,"marginLeft")==getCss(parentNode,"marginRight"))
   {
    marginAuto=true;
   }
  }
  if(!relative)
  {
   left+=parentNode.offsetLeft;
   top+=parentNode.offsetTop;
  }else{
   if(getCss(parentNode,"position")=="relative" || getCss(parentNode,"position")=="absolute")
   {
    rleft+=parentNode.offsetLeft;
    rtop+=parentNode.offsetTop;
   }
  }
  parentNode=parentNode.parentNode;
 }
 while(parentNode.tagName.toLowerCase()!="body")
 var hack=document.getElementById("__hack__");
 var firfoxchromeie8ie9=false;//判断浏览器
 if(hack==null)
 {
  var hackHtml=document.createElement('<div style="background-color:#000000; background-color:#888888\\0; background-color:#999999\\9\\0; *background-color:#777777; _background-color:#666666;" id="__hack__" ></div>');
  document.getElementsByTagName("body")[0].appendChild(hackHtml);
  hack=document.getElementById("__hack__");
 }
 var version=hack.style.backgroundColor;
 if(version=="#000000" || version=="rgb(0, 0, 0)" || version=="#888888" || version=="rgb(153, 153, 153)")
 {
  firfoxchromeie8ie9=true;
 }
 if(firfoxchromeie8ie9 && (relative || marginAuto))
 {
  left=oleft+rleft;
  top=otop+rtop;
 }else if(relative){
  left+=rleft;
  top+=rtop;
 }
 return {left:left,top:top};
}
function getCss(obj, prop) {     //IE中使用的是obj.currentStyle方法,而FF是用的是getComputedStyle 方法
 //if(typeof(obj.style[prop])!="undefined")
 if(obj.style[prop]!="")
 {
  return obj.style[prop];
 }
   if (obj.currentStyle) {     //判断IE
        return obj.currentStyle[prop];     
   }     
    else if (window.getComputedStyle) {     //判断FF 
        propprop = prop.replace (/([A-Z])/g, "-$1");           
       propprop = prop.toLowerCase ();        
         return document.defaultView.getComputedStyle (obj,null)[prop];
    }      
    return null;   
}

这里会有个bug,在firefox下,如果margin:auto;被写在外部文件中的话,那么目前据我所知没有办法准确地去判断当前元素有没有margin:auto;属性。避免出错的方法就是在所有带margin:auto的元素中加入position:relative;

 

唉,坑爹了。。。今天才发现有个叫offsetparent的东西!!!!这个可以完美解决我上述说得如此复杂的东西,

offsetParent:是指元素最近的定位(relative,absolute)祖先元素,如果没有祖先元素是定位的话,会指向body元素

       作用:元素的偏移量(offsetLeft,offsetTop)就是以这个祖先元素为参考点的

原本就是很简单的东西,非给自己复杂化了。

这篇关于关于offsetLeft与position:relative,margin:auto;的一些关系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986010

相关文章

python安装whl包并解决依赖关系的实现

《python安装whl包并解决依赖关系的实现》本文主要介绍了python安装whl包并解决依赖关系的实现,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录一、什么是whl文件?二、我们为什么需要使用whl文件来安装python库?三、我们应该去哪儿下

MYSQL关联关系查询方式

《MYSQL关联关系查询方式》文章详细介绍了MySQL中如何使用内连接和左外连接进行表的关联查询,并展示了如何选择列和使用别名,文章还提供了一些关于查询优化的建议,并鼓励读者参考和支持脚本之家... 目录mysql关联关系查询关联关系查询这个查询做了以下几件事MySQL自关联查询总结MYSQL关联关系查询

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理

数据依赖基础入门:函数依赖与数据库设计的关系

在数据库设计中,数据依赖 是一个重要的概念,它直接影响到数据库的结构和性能。函数依赖 作为数据依赖的一种,是规范化理论的基础,对数据库设计起着至关重要的作用。如果你是一名数据库设计的初学者,这篇文章将帮助你理解函数依赖及其在数据库设计中的应用。 什么是数据依赖? 数据依赖 是指同一关系中属性间的相互依赖和制约关系,它是数据库设计中语义的体现。在现实世界中,数据之间往往存在某种依赖关系,而这

c++ 和C语言的兼容性关系

C++ 和 C 语言有很高的兼容性,但也存在一些差异和限制。下面是它们的兼容性关系的详细介绍: 兼容性 C++ 是 C 的超集: C++ 语言设计为兼容 C 语言的语法和功能,大部分 C 代码可以在 C++ 编译器中编译运行。 标准库兼容性: C++ 标准库包含了 C 标准库的内容,如 stdio.h、stdlib.h、string.h 等头文件,但 C++ 的标准库也提供了额外的功能,如

七、Maven继承和聚合关系、及Maven的仓库及查找顺序

1.继承   2.聚合   3.Maven的仓库及查找顺序

file-max与ulimit的关系与差别

http://zhangxugg-163-com.iteye.com/blog/1108402 http://ilikedo.iteye.com/blog/1554822

【编程底层原理】方法区、永久代和元空间之间的关系

Java虚拟机(JVM)中的内存布局经历了几个版本的变更,其中方法区、永久代和元空间是这些变更中的关键概念。以下是它们之间的关系: 一、方法区: 1、方法区是JVM规范中定义的一个概念,它用于存储类信息、常量、静态变量、即时编译器编译后的代码等数据。 3、它是JVM运行时数据区的一部分,与堆内存一样,是所有线程共享的内存区域。 二、永久代(PermGen): 1、在Java SE 7之前,