jacascript 偏移量offset、客户区client
前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!
偏移量
偏移量(offset dimension)是 javascript 中的一个重要的概念。涉及到偏移量的主要是offsetLeft、offsetTop、offsetHeight、offsetWidth这四个属性,还有一个偏移参照,定位父级 offsetParent。
定位父级
定位父级 offsetParent 的意思是:与当前元素最近的拥有 position 不等于 static 的父级元素,主要分为下列几种情况:
- 元素自身有 fixed 固定定位时,我们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent的结果为 null;firefox浏览器有兼容性问题,返回body
- 元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
- 元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
- <body>元素自身的 parentNode 是null;
<div id="wrapper" style="position: fixed;">
<div id="testa"></div>
</div> <div id="outer" style="position: relative;">
<div id="inner" style="position: absolute;">
<div id="testb"></div>
</div>
</div> <div id="testc"></div>
<script type="text/javascript">
var oWrapper = document.getElementById('wrapper');
var oTestA = document.getElementById('testa'); //元素自身有 fixed 固定定位时,offsetParent的结果为 null;firefox浏览器返回body
console.log(oWrapper.offsetParent);//null
//元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
console.log(oTestA.offsetParent);//<div id="wrapper" style="position: fixed;">...</div> var oOutter = document.getElementById('outer');
var oInner = document.getElementById('inner');
var oTestB = document.getElementById('testb'); //元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
console.log(oOutter.offsetParent);//body
//元素自身无 fixed 定位,且父级元素存在拥有 position 不等于 static 的元素,offsetParent 的结果为就是这个元素;
console.log(oInner.offsetParent);//<div id="outer" style="position: relative;">...</div>
console.log(oTestB.offsetParent);//<div id="inner" style="position: absolute;">...</div> var oTestC = document.getElementById('testc');
//元素自身无 fixed 定位,且父级元素都没有 position 定位过,offsetParent 的结果为<body>;
console.log(oTestC.offsetParent);//body var oBody = document.getElementsByTagName('body')[0];
//<body>元素自身的 parentNode 是null;
console.log(oBody.offsetParent);//null
</script>
偏移量大小
偏移量共包括 offsetWidth、offsetHeight、offsetLeft、offsetTop 这四个属性;
offsetWidth
offsetWidth 表示元素在水平方向上占用的空间大小(不包括margin),无单位(以像素px计);
offsetWidth = border + width + padding
offsetHeight
offsetHeight 表示元素在垂直方向上占用的空间大小(不包括margin),无单位(以像素px计);
offsetHeight = border + Height+ padding
如果存在滚动条,offsetWidth/offsetHeight 也包括滚动条的距离;
浏览器一般把垂直滚动条的宽度从width宽度中移出,把水平滚动条的高度从height高度中移出,则滚动条宽度为17px,width 宽度和 height 高度为剩下的83px,
IE8及以下浏览器将垂直滚动条的宽度计算在 width 宽度和 height 高度中;
offsetTop 与 offsetLeft
offsetTop/offsetLeft 表示当前元素与 offsetParent 元素的 border 之间的像素距离(当前元素的 margin + offsetParent 元素的 padding);
如果当前元素设置了 position 与 left/top ,那么 offsetTop/offsetLeft = 当前元素的left/top + 当前元素的margin ;
position 与 left/right/top/bottom 方位属性配合,显示的是当前元素的 margin 外侧到 offsetParent 元素的 border 内侧之间的距离;
如果父级都没有定位则以 body 为准。
IE7及以下浏览器在 offsetTop 属性的处理上存在bug:
- 若父级设置 position: relative,则在IE7及以下浏览器下,offsetTop 值为 offsetParent 元素的 padding-bottom 值;
- 若父级设置 position: aboslute(或其他触发 haslayout 的条件),offsetTop 值为 offsetParent 元素的 padding-bottom 值和当前元素的 margin-top 值的较大值;
<style type="text/css">
*{padding: 0;margin: 0;}
#wrapper{
position: relative;
width: 400px;
height: 400px;
padding: 30px;
border-width: 10px;
margin: 20px;
border-color: #ff0;
border-style: solid;
background-color: #333;
}
#test{
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 150px;
padding: 20px 30px 40px 50px;/*上右下左*/
border-width: 50px 30px 40px 20px;
margin: 30px 50px 20px 40px;
border-color: #f0f;
border-style: solid;
background-color: #0ff;
}
</style>
<div id="wrapper">
<div id="test"></div>
</div>
<script>
var oTest= document.getElementById('test'); //offsetWidth = border-left + border-right + width + padding-left + padding-right
//230=30+20+100+30+50
console.log(oTest.offsetWidth);//230 //offsetHeight = border-top + border-bottom + width + padding-top + padding-bottom
//300=50+40+150+20+40
console.log(oTest.offsetHeight);//300 //offsetTop 表示元素的上外边距至 offsetParent 元素的上内边距之间的像素距离;
//60=30+100
console.log(oTest.offsetTop);// 130 //offsetLeft 表示元素的左外边距至 offsetParent 元素的左内边距之间的像素距离;
//70=40+100
console.log(oTest.offsetLeft);// 140
</script>
页面偏移
要知道某个元素在页面上的偏移量,将这个元素的 offsetLeft/offsetTop 与其 offsetParent 的 offsetLeft/offsetTop 相加,并加上 offsetParent 的相应方向的边框border,如此循环直到根元素,就可以得到元素到页面的偏移量;
在默认情况下,IE8及以下浏览器下如果使用 currentStyle() 方法获取<html>和<body>(甚至普通div元素)的边框宽度都是medium,而如果使用 clientLeft/clientTop 获取边框宽度,则是实际的数值;
<style type="text/css">
*{padding: 0;margin: 0;}
#wrapper{
position: relative;
width: 400px;
height: 400px;
padding: 30px;
border-width: 10px;
margin: 20px;
border-color: #ff0;
border-style: solid;
background-color: #333;
}
#test{
position: absolute;
width: 100px;
height: 150px;
padding: 20px 30px 40px 50px;/*上右下左*/
border-width: 50px 30px 40px 20px;
margin: 30px 50px 20px 40px;
border-color: #f0f;
border-style: solid;
background-color: #0ff;
}
</style>
<div id="wrapper">
<div id="test"></div>
</div>
<script>
function getElementLeft(obj){
var actualLeft = obj.offsetLeft;
var current = obj.offsetParent;
while(current != null){
actualLeft += current.offsetLeft + current.clientLeft;
current = current.offsetParent;
}
return actualLeft + 'px';
}
function getElementTop(obj){
var actualTop = obj.offsetTop;
var current = obj.offsetParent;
while(current != null){
actualTop += current.offsetTop + current.clientTop;
current = current.offsetParent;
}
return actualTop + 'px';
} var oWrapper= document.getElementById('wrapper');
var oTest= document.getElementById('test'); console.log(oWrapper.offsetLeft);//20
console.log(oTest.offsetLeft);//70
//100=70+20+10
console.log(getElementLeft(oTest));//100px console.log(oWrapper.offsetTop);//20
console.log(oTest.offsetTop);//60
//90=60+20+10
console.log(getElementTop(oTest));//90px
</script>
客户区
客户区大小 client 指的是元素内容及其内边距所占据的空间大小;
盒子调用,指盒子本身;body/html调用,指可视区域大小。
clientWidth 属性返回元素节点的客户区宽度;clientWidth = padding + width
clientHeight 属性返回元素节点的客户区高度;clientHeight = padding + height
滚动条宽度不计算在内;
clientLeft 属性返回左边框的宽度;
clientTop 属性返回上边框的宽度;
如果 display 为 inline 时,clientHeight、clientWidth、clientLeft 和 clientTop 属性都返回0;
<div id="divTest" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></div>
<span id="spanTest" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></span>
<script>
var oDivTest = document.getElementById('divTest');
var oSpanTest = document.getElementById('spanTest');
//120(10+100+10)
console.log(oDivTest.clientHeight);//120
console.log(oDivTest.clientWidth);//120 console.log(oDivTest.clientLeft);//1
console.log(oDivTest.clientTop);//1 //如果 display 为inline 时,clientHeight、clientWidth、clientLeft和clientTop属性属性都返回0
console.log(oSpanTest.clientHeight);//0
console.log(oSpanTest.clientWidth);//0
console.log(oSpanTest.clientLeft);//0
console.log(oSpanTest.clientTop);//0
</script>
页面大小
常用 document.documentElement.clientWidth/clientHeight 属性来表示可视区域页面大小(不包含滚动条宽度);
另一个对常用的表示页面大小的属性是 window.innerHeight/innerWidth 属性(包含滚动条宽度);
innerHeight 和 innerWidth 表示的是浏览器窗口大小减去菜单栏、地址栏等剩余的页面尺寸,由于滚动条是属于页面的,所以包含滚动条;
IE8及以下浏览器不支持 innerHeight 和 innerWidth 属性;
如果没有滚动条(页面最大化),这两类属性在电脑端表示同样的值,但是却表示不同的含义。在移动端,innerWidth 和 innerHeight 表示的是视觉视口,即用户正在看到的网站的区域;而document.documentElement.clientWidth 和 clientHeight 表示的是布局视口,指CSS布局的尺寸。
<body style="overflow:scroll">
<script>
//1349=1366-17
console.log(document.documentElement.clientWidth);
//621=638-17
console.log(document.documentElement.clientHeight); console.log(window.innerWidth);//1366
console.log(window.innerHeight);//638
</script>
</body>
clientX 和 clientY
event 对象是 JavaScript 中最重要的对象之一,它代表了各种事件的状态,在各种事件的事件处理中经常用到,比如键盘活动、鼠标活动等等;
clientX,鼠标指针位置相对于窗口客户区域的 x 坐标,(event调用); 其中客户区域不包括窗口自身的控件和滚动条;
clientY,鼠标指针位置相对于窗口客户区域的 y 坐标,(event调用); 其中客户区域不包括窗口自身的控件和滚动条;
offsetX,鼠标指针位置相对于触发事件的对象的 x 坐标;
offsetY,鼠标指针位置相对于触发事件的对象的 y 坐标;
screenX,鼠标指针位置相对于用户屏幕的 x 坐标;
screenY,鼠标指针位置相对于用户屏幕的 y 坐标;
<style type="text/css">
*{padding: 0;margin: 0;}
body{height: 1000px;}
p{height: 300px;width: 300px;background: #f0f;}
</style>
<body>
<p>请在文档中点击。控制台会提示出鼠标指针的 x 和 y 坐标。</p> <script type="text/javascript">
var oBody = document.getElementsByTagName('body')[0];
var oP = document.getElementsByTagName('p')[0];
oBody.onmousedown = function(ev){
ev = ev || event; clX = ev.clientX;
clY = ev.clientY;
console.log("鼠标clientX的值是: " + clX + ", 鼠标clientY的值是: " + clY); scX = ev.screenX;
scY = ev.screenY;
console.log("鼠标screenX的值是: " + scX + ", 鼠标screenY的值是: " + scY);
} oP.onmousedown = function(ev){
ev = ev || event; ofX = ev.offsetX;
ofY = ev.offsetY;
console.log("鼠标相对于p标签的offsetX的值是: " + ofX + ", 鼠标相对于p标签的offsetY的值是: " + ofY);
}
</script>
</body>
jacascript 偏移量offset、客户区client的更多相关文章
- MFC自绘框架窗口客户区
利用MFC开发用户界面往往需要需要根据要求进行界面美化,界面的美化包括很多内容,比如说界面各功能模块空间布局,控件位置选择,各功能模块区域的字体.背景颜色选择.添加位图,标题栏.菜单栏.状态栏等的重绘 ...
- rocketMq 消息偏移量 Offset
消息偏移量 Offset queue0 offset 0 0-20 offset 4 20-40 纠错:每条消息的tag对应的HashCode. queue1 offset 1 0-20 ...
- JS中的offset scroll event client
一.offset 一般用来检测盒子的偏移.位移,都是只读属性,不能赋值 offsetWidth和offsetHeight表示的是:调用者盒子的宽和高,包括盒子自身的padding和border off ...
- offset系列、client系列、scroll系列
offset系列.client系列 <style> .testDOM { width: 200px; height: 200px; background-color: #2de; pa ...
- 元素偏移量 offset 系列
offset 概述 offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移).大小等. 获得元素距离带有定位父元素的位置 获得元素自身的大小(宽度高度) 注意 ...
- jq获取元素偏移量offset()
解释: 1 获取匹配元素在当前视口的相对偏移. 2 返回的对象包含两个整型属性:top 和 left demo1: 获取top与left var aaa = $(".aaa "); ...
- pwn之偏移量offset
0x7fffffffdd00: 0x4141414141414141 0x4141414141414141 0x7fffffffdd10: 0x4141414141414141 0x414141414 ...
- 元素大小-偏移量(offset)客户区大小(client)滚动大小(scroll)
一.偏移量---offset 1.定位父级 在理解偏移大小之前,首先要理解offsetParent.人们并没有把offsetParent翻译为偏移父级,而是翻译成定位父级,很大原因是offsetPar ...
- 深入理解客户区尺寸client
前面的话 关于元素尺寸,一般地,有偏移大小offset.客户区大小client和滚动大小scroll.前文已经介绍过偏移属性,后文将介绍scroll滚动大小,本文主要介绍客户区大小client 客户区 ...
随机推荐
- [JLOI2014] 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- 大数运算的算法设计和C++实现
1.背景 工作中遇到过需要进行极大数据的存储和运算的场景,当时使用Python解决了这个问题,在Python中,整数没有位数限制,使用起来很方便.但是当程序主体使用C/C++实现时,就比较麻烦.所以考 ...
- Lucene-02:搜索初步
承接上一篇文章. package com.amazing; import java.io.File; import java.io.IOException; import org.apache.luc ...
- poj-1207 THE 3n+1 problem
Description Problems in Computer Science are often classified as belonging to a certain class of pro ...
- ElasticSearch的安装
一.安装javaSE环境(已配java环境变量的请直接跳过) 1.从Java JDK 官网下载适合自己的jdk版本.(我自己用的jdk1.7) 2.安装jdk后,配置java环境变量(ps:比较喜欢简 ...
- wipefs进程
wipefs进程是啥,占用了百分之90多的cpu wipefs进程是啥,占用了百分之90多的cpu,把这个进程干掉了,过了一天又自动启动了,很多朋友应该遇到过类似的问题. wipefs是linux自带 ...
- Python中的PYTHONPATH环境变量
PYTHONPATH是Python中一个重要的环境变量,用于在导入模块的时候搜索路径.可以通过如下方式访问: >>> import sys >>> sys.path ...
- OSI七层协议模型、TCP/IP四层模型学习笔记
1. OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行 ...
- RESTful三问
我觉得学习一个技术,其实就是要弄明白三件事情:是什么(what),为什么(why),怎么用(how).正是所谓的三W方法. 所以打算总结一个"三问"系列.为了自己学习,也分享给别人 ...
- D的下L
D的小L 时间限制:4000 ms | 内存限制:65535 KB 难度:2 描述 一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给 ...