【JavaScript】全面解析offsetLeft、offsetTop

 

假设 obj 为某个 HTML 控件。
obj.offsetLeft 指 obj 距离左方或上层控件的位置,整型,单位像素。

obj.offsetRight 指 obj 距离右方或上层控件的位置,整型,单位像素。

obj.offsetTop 指 obj 距离上方或上层控件的位置,整型,单位像素。

obj.offsetBottom 指 obj 距离下方或上层控件的位置,整型,单位像素。

obj.offsetWidth 指 obj 控件自身的宽度,整型,单位像素。

obj.offsetHeight 指 obj 控件自身的高度,整型,单位像素

我们对前面提到的“上方或上层”与“左方或上层”控件作个说明。

例如:
<div id="tool">
<input type="button" value="提交">
<input type="button" value="重置">
</div>

“提交”按钮的 offsetTop 指“提交”按钮距“tool”层上边框的距离,因为距其上边最近的是 “tool” 层的上边框。
“重置”按钮的 offsetTop 指“重置”按钮距“tool”层上边框的距离,因为距其上边最近的是 “tool” 层的上边框。

“提交”按钮的 offsetLeft 指“提交”按钮距“tool”层左边框的距离,因为距其左边最近的是 “tool” 层的左边框。
“重置”按钮的 offsetLeft 指“重置”按钮距“提交”按钮右边框的距离,因为距其左边最近的是“提交”按钮的右边框。

以上属性在 FireFox 中也有效。

window.screen.availWidth     返回当前屏幕宽度(空白空间)  
window.screen.availHeight     返回当前屏幕高度(空白空间)  
window.screen.width     返回当前屏幕宽度(分辨率值)  
window.screen.height     返回当前屏幕高度(分辨率值)  
window.document.body.offsetHeight;     返回当前网页高度  
window.document.body.offsetWidth;     返回当前网页宽度  

我们这里说说四种浏览器对 document.body 的 clientHeight、offsetHeight 和 scrollHeight 的解释。

这四种浏览器分别为IE(Internet Explorer)、NS(Netscape)、Opera、FF(FireFox)。

clientHeight
大家对 clientHeight 都没有什么异议,都认为是内容可视区域的高度,也就是说页面浏览器中可以看到内容的这个区域的高度,一般是最后一个工具条以下到状态栏以上的这个区域,与页面内容无关。

offsetHeight
IE、Opera 认为 offsetHeight = clientHeight + 滚动条 + 边框。
NS、FF 认为 offsetHeight 是网页内容实际高度,可以小于 clientHeight。

scrollHeight
IE、Opera 认为 scrollHeight 是网页内容实际高度,可以小于 clientHeight。
NS、FF 认为 scrollHeight 是网页内容高度,不过最小值是 clientHeight。

简单地说
clientHeight 就是透过浏览器看内容的这个区域高度。
NS、 FF 认为 offsetHeight 和 scrollHeight 都是网页内容高度,只不过当网页内容高度小于等于 clientHeight 时,scrollHeight 的值是 clientHeight,而 offsetHeight 可以小于 clientHeight。
IE、Opera 认为 offsetHeight 是可视区域 clientHeight 滚动条加边框。scrollHeight 则是网页内容实际高度。

同理
clientWidth、offsetWidth 和 scrollWidth 的解释与上面相同,只是把高度换成宽度即可。

再附上一些

网页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth   (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度:window.screen.availWidth;

对于因为使用web标准失效比如document.body.scrollTop总是零的原因

解决方法如下:

原来在HTML文件头部声明了这样一句:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

改成这样就好了:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
但页面稍有变化,感觉不爽,于是又在google里找,终于发现这是IE5与IE6的区别:

var scrollPos;
if (typeof window.pageYOffset != 'undefined') {
   scrollPos = window.pageYOffset;
}
else if (typeof document.compatMode != 'undefined' &&
     document.compatMode != 'BackCompat') {
   scrollPos = document.documentElement.scrollTop;
}
else if (typeof document.body != 'undefined') {
   scrollPos = document.

 

一、第一个小例子

 1 <body>
 2 <style>
 3 body { margin:0;  }
 4 .box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; }
 5 .box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; }
 6 .box3 { width:100px; height:100px; margin:100px; background:#999;}
 7 </style>
 8 <div class="box1">
 9     <div class="box2">
10         <div class="box3"></div>
11     </div>
12 </div>
13 <script>
14     var oBox1 = document.querySelector('.box1');
15     var oBox2 = document.querySelector('.box2');
16     var oBox3 = document.querySelector('.box3');
17     
18     console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);
19     console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);
20     console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
21 </script>
22 </body>

①第一个例子中,三个div的上一级的定位元素都是body,body是最外层的定位元素,三个div获取到的offsetLeft值跟offsetTop值都是相对于body的偏移量。

二、第二个小例子(给box1添加相对定位)

<body>
<style>
body { margin:0;  }
.box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative;}
.box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; }
.box3 { width:100px; height:100px; margin:100px; background:#999;}
</style>
<div class="box1">
    <div class="box2">
        <div class="box3"></div>
    </div>
</div>
<script>
    var oBox1 = document.querySelector('.box1');
    var oBox2 = document.querySelector('.box2');
    var oBox3 = document.querySelector('.box3');
    
    console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);
    console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);
    console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
</script>
</body>

②第二个例子中,box1加上了相对定位,这时候box2,box3的上一级定位元素不再是body了,这时他们获取到的offsetLeft值跟offsetTop值都是相对于box1的偏移量。而box1的上一级定位元素还是body,所以他的偏移量还是相对于body的。

三、第三个小例子(给box1,box2添加相对定位)

 1 <body>
 2 <style>
 3 body { margin:0;  }
 4 .box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative; }
 5 .box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; position:relative; }
 6 .box3 { width:100px; height:100px; margin:100px; background:#999;}
 7 </style>
 8 <div class="box1">
 9     <div class="box2">
10         <div class="box3"></div>
11     </div>
12 </div>
13 <script>
14     var oBox1 = document.querySelector('.box1');
15     var oBox2 = document.querySelector('.box2');
16     var oBox3 = document.querySelector('.box3');
17     
18     console.log('box1: '+ oBox1.offsetLeft +','+ oBox1.offsetTop);
19     console.log('box2: '+ oBox2.offsetLeft +','+ oBox2.offsetTop);
20     console.log('box3: '+ oBox3.offsetLeft +','+ oBox3.offsetTop);
21 </script>
22 </body>

③第三个例子中,box1跟box2都加上了相对定位,这时候,box3的上一级定位元素变成是box2,box2的上一级定位元素是box1,box1的上一级定位元素还是body。所以这时候就出现了。三个div的偏移量都为100;

四、解析

通过上面的三个例子不难看出,offsetLeft值跟offsetTop值的获取跟父级元素没关系,而是跟其上一级的定位元素(除position:static;外的所有定位如fixed,relative,absolute)有关系。 

  所以给父级添加定位之后,offset的偏移值就会变成相对于父级的偏移值.(除了position:static;外的所有定位,如fixed,relative,absolute都会使偏移值的参考对象变为父级))

五、扩展(在第三个例子中,假如我想获取到box3到浏览器窗口的偏移量,该怎么去获取呢?)

思路很简单,就是把元素本身的偏移量跟所有上级定位元素的偏移量都加起来就可以了,问题又来了,假如我们不知道他有几个上级定位元素呢?

其实也不难。js不但提供了offsetLeft、offsetTop方法,还提供了offsetParent(获取上一级定位元素对象)的方法。所以现在我们只需封装一个函数就可以了。

 

 1 function offset(obj,direction){
 2     //将top,left首字母大写,并拼接成offsetTop,offsetLeft
 3     var offsetDir = 'offset'+ direction[0].toUpperCase()+direction.substring(1);
 4         
 5     var realNum = obj[offsetDir];
 6     var positionParent = obj.offsetParent;  //获取上一级定位元素对象
 7         
 8     while(positionParent != null){
 9     realNum += positionParent[offsetDir];
10     positionParent = positionParent.offsetParent;
11     }
12     return realNum;
13 }

运用程序中

 1 <body>
 2 <style>
 3 body { margin:0;  }
 4 .box1 { width:300px; height:300px; margin:100px; background:#333; overflow:hidden; position:relative; }
 5 .box2 { width:200px; height:200px; margin:100px; background:#666; overflow:hidden; position:relative; }
 6 .box3 { width:100px; height:100px; margin:100px; background:#999;}
 7 </style>
 8 <div class="box1">
 9     <div class="box2">
10         <div class="box3"></div>
11     </div>
12 </div>
13 <script>
14     var oBox1 = document.querySelector('.box1');
15     var oBox2 = document.querySelector('.box2');
16     var oBox3 = document.querySelector('.box3');
17         
18     function offset(obj,direction){
19         //将top,left首字母大写,并拼接成offsetTop,offsetLeft
20         var offsetDir = 'offset'+ direction[0].toUpperCase()+direction.substring(1);
21         
22         var realNum = obj[offsetDir];
23         var positionParent = obj.offsetParent;  //获取上一级定位元素对象
24         
25         while(positionParent != null){
26             realNum += positionParent[offsetDir];
27             positionParent = positionParent.offsetParent;
28         }
29         return realNum;
30     }
31     console.log('box1: '+ offset(oBox1,'left') +','+ offset(oBox1,'top'));
32     console.log('box2: '+ offset(oBox2,'left') +','+ offset(oBox2,'top'));
33     console.log('box3: '+ offset(oBox3,'left') +','+ offset(oBox3,'top'));
34 </script>
35 </body>

原文地址:https://www.cnblogs.com/yuer20180726/p/11167483.html