频道栏目
首页 > 网络 > 其他 > 正文

定位父级offsetParent及偏移大小

2017-05-16 09:35:00      个评论      
收藏   我要投稿

偏移量(offset dimension)是javascript中的一个重要的概念。涉及到偏移量的主要是offsetLeft、offsetTop、offsetHeight、offsetWidth这四个属性。当然,还有一个偏移参照——定位父级offsetParent。本文将详细介绍该部分内容。

\

定位父级

  在理解偏移大小之前,首先要理解offsetParent。人们并没有把offsetParent翻译为偏移父级,而是翻译成定位父级,很大原因是offsetParent与定位有关

  定位父级offsetParent的定义是:与当前元素最近的经过定位(position不等于static)的父级元素,主要分为下列几种情况

  【1】元素自身有fixed定位,offsetParent的结果为null

  当元素自身有fixed固定定位时,我们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent的结果为null

  [注意]firefox浏览器有兼容性问题

  【2】元素自身无fixed定位,且父级元素都未经过定位,offsetParent的结果为
<script>console.log(test.offsetParent);//</script>

  【3】元素自身无fixed定位,且父级元素存在经过定位的元素,offsetParent的结果为离自身元素最近的经过定位的父级元素



<script>console.log(test.offsetParent);//</script>

  【4】

元素的parentNode是null
console.log(document.body.offsetParent);//null

IE7-浏览器Bug

  对于定位父级offsetParent来说,IE7-浏览器存在以下bug

  【bug1】当元素本身经过绝对定位或相对定位,且父级元素无经过定位的元素时,IE7-浏览器下,offsetParent是

<script>//IE7-浏览器返回,其他浏览器返回console.log(test.offsetParent);</script>
<script>//IE7-浏览器返回,其他浏览器返回console.log(test.offsetParent);</script>
<script>//firefox并没有考虑固定定位的问题,返回,其他浏览器都返回nullconsole.log(test.offsetParent);</script>

  【bug2】如果父级元素存在触发haslayout的元素或经过定位的元素,且offsetParent的结果为离自身元素最近的经过定位或触发haslayout的父级元素

  [注意]关于haslayout的详细信息移步至此

<script>//IE7-浏览器返回,其他浏览器返回console.log(test.offsetParent);</script>


<script>//IE7-浏览器返回,其他浏览器返回console.log(test.offsetParent);</script>


<script>//所有浏览器都返回console.log(test.offsetParent);</script>

偏移量

  偏移量共包括offsetHeight、offsetWidth、offsetLeft、offsetTop这四个属性

offsetWidth

  offsetWidth表示元素在水平方向上占用的空间大小,无单位(以像素px计)

offsetWidth=border-left-width+padding-left+width+padding-right+border-right-width;

offsetHeight

  offsetHeight表示元素在垂直方向上占用的空间大小,无单位(以像素px计)

offsetHeight=border-top-width+padding-top+height+padding-bottom+border-bottom-width
<script>//122=1+10+100+10+1console.log(test.offsetWidth);
console.log(test.offsetHeight);</script>

  [注意]如果存在垂直滚动条,offsetWidth也包括垂直滚动条的宽度;如果存在水平滚动条,offsetHeight也包括水平滚动条的高度

<script>//IE8-浏览器将垂直滚动条的宽度计算在width宽度和height高度中,width和height的值仍然是100px;//而其他浏览器则把垂直滚动条的宽度从width宽度中移出,把水平滚动条的高度从height高度中移出,则滚动条宽度为17px,width宽度和height高度为剩下的83pxif(window.getComputedStyle){
console.log(getComputedStyle(test).width,getComputedStyle(test).height)//83px}else{
console.log(test.currentStyle.width,test.currentStyle.height);//100px}//122=1+10+100+10+1console.log(test.offsetWidth,test.offsetHeight);</script>

offsetTop

  offsetTop表示元素的上外边框至offsetParent元素的上内边框之间的像素距离

offsetLeft

  offsetLeft表示元素的左外边框至offsetParent元素的左内边框之间的像素距离

<script>//15=test.marginTop(10)+out.paddingTop(5)alert(test.offsetTop);//15=test.marginLeft(10)+out.paddingLeft(5)alert(test.offsetLeft);</script>

IE7-Bug

  IE7-浏览器在offsetTop属性的处理上存在bug

  【1】若父级设置position: relative,则在IE7-浏览器下,offsetTop值为offsetParent元素的paddingBottom值

<script>//其他浏览器返回15(5+10),而IE7-浏览器返回5console.log(test.offsetTop);</script>

  【2】若父级设置position: aboslute(或其他触发haslayout的条件),offsetTop值为offsetParent元素的paddingBottom值和当前元素的marginTop值的较大值

<script>//其他浏览器返回15(5+10),而IE7-浏览器返回10(10和5的较大值)console.log(test.offsetTop);</script>

页面偏移

  要知道某个元素在页面上的偏移量,将这个元素的offsetLeft和offsetTop与其offsetParent的相同属性相加,并加上offsetParent的相应方向的边框,如此循环直到根元素,就可以得到元素到页面的偏移量

  [注意]在默认情况下,IE8-浏览器下如果使用currentStyle()方法获取

和(甚至普通div元素)的边框宽度都是medium,而如果使用clientLeft(或clientTop)获取边框宽度,则是实际的数值
html,body{border:0;}body{margin:0;}
functiongetElementLeft(element){varactualLeft=element.offsetLeft;varcurrent=element.offsetParent;while(current!=null){
actualLeft+=current.offsetLeft+current.clientLeft;
current=current.offsetParent;
}returnactualLeft+'px';
}functiongetElementTop(element){varactualTop=element.offsetTop;varcurrent=element.offsetParent;while(current!=null){
actualTop+=current.offsetTop+current.clientTop;
current=current.offsetParent;
}returnactualTop+'px';
}
<script>//其他浏览器返回31(10+20+1),而IE7-浏览器返回21((20和10的较大值)+1)console.log(getElementTop(test));//所有浏览器返回31(10+20+1)console.log(getElementLeft(test));</script>

注意事项

  【1】所有偏移量属性都是只读的

<script>console.log(test.offsetWidth);//100//IE8-浏览器会报错,其他浏览器则静默失败test.offsetWidth=10;
console.log(test.offsetWidth);//100</script>

  【2】如果给元素设置了display:none,则它的偏移量属性都为0

  【3】每次访问偏移量属性都需要重新计算
<script>console.time("time");for(vari=0;i<100000;i++){vara=test.offsetWidth;
}
console.timeEnd('time');//65.129ms</script>
<script>console.time("time");vara=test.offsetWidth;for(vari=0;i<100000;i++){varb=a;
}
console.timeEnd('time');//1.428ms</script>
上一篇:搭建NIS服务器实现用户集中化认证
下一篇:使用puppet实现自动化运维
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训

版权所有: 红黑联盟--致力于做实用的IT技术学习网站