前端学习_彻底弄清offset

前端开发技术的起源与历史
现在前端开发主要技术
前端的开发技术

很多初学者对于JavaScript中的offset、scroll、client一直弄不明白!这一节先来解释下offset的用法

一、关于offset,我们要弄明白什么

在这里我们可以看到,关于offset共有5个东西需要弄清楚:

1、offsetParent

2、offsetTop

  3、offsetLeft

4、offsetWidth

5、offsetHeight

我们根据难易程度把以上5点分为三类来讲解。
在分析之前先来看段测试代码:
代码片段 1

360安全浏览器:

前端攻城狮学习:让你彻底弄清offset
Chrome浏览器:

前端攻城狮学习:让你彻底弄清offset
Firefox 浏览器:

前端攻城狮学习:让你彻底弄清offset
IE7 :

前端攻城狮学习:让你彻底弄清offset
IE8:

前端攻城狮学习:让你彻底弄清offset

二、offsetWidth与offsetHeight

大家可以看到,上面图二~图五中的共同点是 offsetWidth与offsetHeight是一致的,因此这里放到地起讲。

MDN中对offsetWidth的概述和描述是:
[code]Returns the layout width of an element.
Typically, an element’s offsetWidth is a measurement which includes the element borders, the element horizontal padding, the element vertical scrollbar (if present, if rendered) and the element css width.[/code]
也就是元素的可视宽度,这个宽度包括元素的边框(border),水平padding,垂直滚动条宽度,元素本身宽度等。
只是我们的示例中没有水平和垂直滚动条。另外经过测试可以发现,即使元素加上水平或垂直滚动条,offsetWidth跟offsetHeight的值是不会更改的,因为浏览器渲染时把滚动条的宽度(或高度)算在了元素本身的宽度(或高度)中了。
通过代码及图中数值,我们不难看出:

offsetWidth=(border-width)*2+(padding-left)+(width)+(padding-right)

offsetHeight=(border-width)*2+(padding-top)+(height)+(padding-bottom)

对这两个概念就总结到这里,大家现在弄明白了吗?

三、offsetLeft与offsetTop

  offsetWidth与offsetHeight有个特点,就是这两个属性的值只与该元素有关,与周围元素(父级和子级元素无关)。

然而,offsetLeft与offsetTop却不是这样,这两个属性与offsetParent有关,但在我们讲到offsetParent之前,我们先不管offsetParent是什么及怎么判断,我们只要知道offsetLeft和offsetTop与offsetParent有关就行了,上面的示例中offsetParent就是body。

MSDN上对offsetLeft的定义是:
[code] Retrieves the calculated left position of the object relative to the layout or coordinate parent, as specified by the offsetParent property
etrieves the calculated left position of the object relative to the layout or coordinate parent, as specified by the offsetParent property
[/code]

也就是返回对象元素边界的左上角顶点相对于offsetParent的左上角顶点的水平偏移量。从这个定义中我们可以明确地知道offsetLeft与当前元素的margin-left和offsetParent的padding-left有关。也就是说应该是:

offsetLeft=(offsetParent的padding-left)+(中间元素的offsetWidth)+(当前元素的margin-left)。

offsetTop=(offsetParent的padding-top)+(中间元素的offsetHeight)+(当前元素的margin-top)。

但通过上面的例子我们可以看到,当offsetParent为body时,对于offsetLeft与offsetTop的值有三种,分别是:IE6/7中的40,IE8/9/10 和 Chrome中的70,以及FireFox中的50。

通过这些数值我们可以知道,当offsetParent为body时情况比较特殊:

IE8/9/10及Chrome中,offsetLeft = (body的margin-left)+(body的border-width)+(body的padding-left)+(当前元素的margin-left)。

FireFox中,offsetLeft = (body的margin-left)+(body的padding-left)+(当前元素的margin-left)。

四、offsetParent

终于到offsetParent了。

offsetParent属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过css定位的容器元素。 如果这个容器元素未进行css定位, 则offsetParent属性的取值为根元素的引用。

总的来说两条规则:

1、如果当前元素的父级元素没有进行css定位(position为absolute或relative),offsetParent为body。

2、如果当前元素的父级元素中有css定位(position为absolute或relative),offsetParent取最近的那个父级元素。

上面的示例就是第1条说的情况,我们来验证一下:

我们把js改为(添加了一行代码:红色部分):

var test = document.getElementById(“test”);
test.innerHTML = “<p>Browser:” + navigator.userAgent + “</p>” +
“<p>offsetParent:” + test.offsetParent.tagName + “</p>” +
“<p>offsetWidth:” + test.offsetWidth + “</p>” +
“<p>offsetHeight:”+test.offsetHeight+”</p>”+
“<p>offsetLeft:”+test.offsetLeft+”</p>”+
“<p>offsetTop:”+test.offsetTop+”</p>”;
FireFox下的效果为:

图六

在其他浏览器中效果相同,都是body。

我们再来验证一下第2条,测试html如下:

<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
</head>
<body>
<style type=”text/css”>
body {
margin:0;
padding:0;
background:#EEE;
}
div,ul,li {
margin:0;
}
li {
height:20px;
line-height:20px;
}

test {

        width:400px;
        height:250px;
        padding:20px;
        background:#F60;
        border:10px solid #888;
    }
    #divtest {
        margin:30px;
        position:relative;
        left:50px;
        top:70px;
        padding:20px;
    }
</style>
<div id="divtest">
    <ul>
        <li>Test</li>
        <li>Test</li>
    </ul>
    <div id="test">
    </div>
</div>
<script>

var test = document.getElementById(“test”);
test.innerHTML = “<p>Browser:” + navigator.userAgent + “</p>” +
“<p>offsetParent:” + test.offsetParent.tagName + “</p>” +
“<p>offsetWidth:” + test.offsetWidth + “</p>” +
“<p>offsetHeight:”+test.offsetHeight+”</p>”+
“<p>offsetLeft:”+test.offsetLeft+”</p>”+
“<p>offsetTop:”+test.offsetTop+”</p>”;
</script>
</body>
</html>
在FireFox中效果为:

图七

在其他浏览器中offsetParent也是一致的。

在这里我们也可以看到,第三点中给出的offsetLeft的计算公式是适用的。

小结
以上的总结希望能对大家有所帮助,在看完本文内容后再回过头来看文章开头部分的那张图(只看offset)部分,是不是清楚了很多?

最后,对于offsetParent为body的情况,现在的主流浏览器IE8/9/10和Chrome及Firefox都跟定义

  offsetLeft=(offsetParent的padding-left)+(中间元素的offsetWidth)+(当前元素的margin-left)。

offsetTop=(offsetParent的padding-top)+(中间元素的offsetHeight)+(当前元素的margin-top)。

前端web开发技术架构
web前端开发技术 课件
前端开发技术和工具
» 本文来自:前端开发者 » 《前端学习_彻底弄清offset》
» 本文链接地址:https://www.rokub.com/6557.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!