Width and Height
offsetLeft offsetTop offsetWidth offsetHeight
offsetWidth offsetHeight
offsetWidth/offsetHeight = width/height + padding + border
offsetParent
offsetParent属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的容器元素。 如果这个容器元素未进行CSS定位, 则offsetParent属性的取值为根元素的引用。
总的来说两条规则:
1、如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body。
2、如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。
offsetLeft offsetTop
当body无margin、border、padding的场合、并且CSS中没有定位(offsetParent为body时):
原则:元素的左(上)外边框至包含元素的左(上)内边框之间的像素距离(图1)。
IE6-7:(预测IE6-7默认当前元素的父级元素中有CSS定位,注意IE6不同的盒模型),值为相邻元素之间的距离。(图4、5)
IE8、Firefox、Chrome、Safari:元素距离浏览器边框的距离。(图2、3)
图1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#BB{
margin:10px;
border:15px solid yellow;
padding:12px;
width:500px;height:400px;
background:red;
/*position: relative;*/
}
#CC{
margin:30px;
border:40px solid black;
padding:10px;
width:500px;
height:250px;
background:blue;
/*position: relative;*/
}
#DD{
margin:20px;
border:30px solid #ccc;
padding:10px;
width:100px;
height:100px;
background:blue;
float: left;
}
#da{
margin:20px;
border:30px solid #555;
padding:10px;
width:100px;
height:100px;
background:blue;
float: left;
}
</style>
</HEAD>
<body>
<div id="BB">
BB
<div>
<div id="CC">
CC
<div id="DD">
DD
</div>
<div id="da">
DA
</div>
</div>
</div>
</div>
<span>
<pre> #BB{margin:10px;border:15px solid yellow;padding:12px; position: relative;}
#CC{margin:30px;border:40px solid black; padding:10px;position: relative;}
#DD{margin:20px;border:30px solid #ccc; padding:10px;width:100px;}
#da{margin:20px;border:30px solid #555; padding:10px; }
</pre>
</span>
</body>
<script type="text/javascript">
function getElementLeft(element) {
var actualLeft = element.offsetLeft;
return actualLeft;
}
function getElementTop(element) {
var actualTop = element.offsetTop;
return actualTop;
}
/*
*
function getElementLeft(element) {
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current!==null) {
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementTop(element) {
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current!==null) {
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
*/
var aa = document.body;
var bb = document.getElementById("BB");
var cc = document.getElementById("CC");
var dd = document.getElementById("DD");
var da = document.getElementById("da");
str = "bodyLeft:"+getElementLeft(aa);
str =str+"<br/>"+"bodyTop:"+getElementTop(aa);
str =str+"<br/>"+"redDivLeft:"+getElementLeft(bb);
str =str+"<br/>"+"redDivTop:"+getElementTop(bb);
str =str+ "<br/>"+"blueDivLeft:"+getElementLeft(cc);
str =str+"<br/>"+"blueDivTop:"+getElementTop(cc);
str =str+ "<br/>"+"innerDivLeft:"+getElementLeft(dd);
str =str+"<br/>"+"innerDivTop:"+getElementTop(dd);
str =str+ "<br/>"+"daDivLeft:"+getElementLeft(da);
str =str+"<br/>"+"daDivTop:"+getElementTop(da);
document.write(str);
</script>
</HTML>
图2
图3
图4
图5
当body无margin、border、padding的场合、并且CSS中都有定位(offsetParent最近的那个父级元素时):
原则:元素的左(上)外边框至包含元素的左(上)内边框之间的像素距离。
IE6-7、Firefox、Chrome、Safari:值为相邻元素之间的距离。并且与上图中的IE7的值基本相同(图6)。
IE8:元素的左(上)外边框至包含元素的左(上)外边框之间的像素距离(图7)。
IE6-7的值与上一种情况比较:未发生变化。
//为#BB、#CC添加代码position: relative;
#BB{
margin:10px;
border:15px solid yellow;
padding:12px;
width:500px;height:400px;
background:red;
position: relative;
}
#CC{
margin:30px;
border:40px solid black;
padding:10px;
width:500px;
height:250px;
background:blue;
position: relative;
}
图6
图7
总结:采用如下代码,基本(还要考虑上面所述的问题)可以获取某个元素在页面上的偏移量。
function getElementLeft(element) {
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current!==null) {
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementTop(element) {
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current!==null) {
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
参考文章:http://www.cnblogs.com/jscode/archive/2012/09/03/2669299.html
obj.clientLeft、obj.clientTop、obj.clientWidth、obj.clientHeight(图8)
obj.scrollLeft、obj.scrollTop、obj.scrollWidth、obj.scrollHeight(图9)
window.sreenTop(sreenX)、window.screenLeft(sreenY)
window.screen.height、window.screen.width 屏幕分辨率的高度宽度
window.screen.availHeight、window.screen.availWidth 屏幕可用工作区的高度宽度
图8
图9
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<body style="margin:20px;border:100px solid black;">
aaaaaaaaaaaaaaaaaaaaaaaaaaa
<div style="width:400px;height:400px;background:red">
bbbbb
<div>
<div id="sss" style="margin:10px;border:150px solid black;padding:100px;width:400px;height:400px;background:blue">
ccc
<div>
</body>
<script type="text/javascript">
function test()
{
var s="";
s+="\r\n body.clientLeft:"+document.body.clientLeft;
s+="\r\n body.clientWidth:"+document.body.clientWidth;
s+="\r\n body.clientHeight:"+document.body.clientHeight;
s+="\r\n body.offsetLeft:"+document.body.offsetLeft;
s+="\r\n body.offsetTop:"+document.body.offsetTop;
s+="\r\n body.offsetWidth:"+document.body.offsetWidth;
s+="\r\n body.offsetHeight:"+document.body.offsetHeight;
s+="\r\n body.scrollWidth:"+document.body.scrollWidth;
s+="\r\n body.scrollHeight:"+document.body.scrollHeight;
s+="\r\n body.scrollTop:"+document.body.scrollTop;
s+="\r\n body.scrollLeft:"+document.body.scrollLeft;
s+="\r\n window.screenTop:"+window.screenTop;
s+="\r\n window.screenLeft:"+window.screenLeft;
s+="\r\n window.screen.height:"+window.screen.height;
s+="\r\n window.screen.width:"+window.screen.width;
s+="\r\n window.screen.availHeight:"+window.screen.availHeight;
s+="\r\n window.screen.availWidth:"+window.screen.availWidth;
s+="\r\n div:clientLeft"+document.getElementById("sss").clientLeft;
s+="\r\n div:clientTop"+document.getElementById("sss").clientTop;
s+="\r\n div:clientWidth"+document.getElementById("sss").clientWidth;
s+="\r\n div:clientHeight"+document.getElementById("sss").clientHeight;
s+="\r\n div:offsetLeft"+document.getElementById("sss").offsetLeft;
s+="\r\n div:offsetTop"+document.getElementById("sss").offsetTop;
s+="\r\n div:offsetWidth"+document.getElementById("sss").offsetWidth;
s+="\r\n div:offsetHeight"+document.getElementById("sss").offsetHeight;
alert(s);
}
test();
</script>
</HTML>
运行结果:
从运行结果中得知:body中、clientWidth与scrollWidth比较:
IE相同、FF相差200(border)、Safari/Chrome相差240(border和margin)
以下内容引用自:http://www.sj63.com/html/201206/201206042342531057004461_1.html
obj.offset[Width|Height|Top|Left] 取控件相对于父控的位置
event.offset[X|Y] 取鼠标相对触发事件的控件中的坐标
event.screen[X|Y] 鼠标相对于屏幕坐标
event.client[X|Y] 鼠标相对于网页坐标在在
obj.scroll[Width|Height|Top|Left] 获取对象滚动的大小
obj.client[Width|Height|Top|Left] 获取对象可见区域的大小
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>无标题文档</title>
<style type="text/css">
div {
font-family: "宋体";
font-size: 12px;
color: #000000;
}
* {
padding: 0;
margin: 0
}
#div1 {
position: absolute;
background-color: #f0f0f0;
width: 200px;
height: 200px;
left: 20px;
top: 0px;
z-index: 1;
}
#div2 {
background-color: #cfc0cf;
width: 200px;
height: 210px;
position: absolute;
left: 261px;
top: 347px;
z-index: 100;
}
#div3 {
background-color: #abbfbf;
width: 200px;
height: 200px;
position: absolute;
left: 20px;
top: 247px;
z-index: 100;
}
#div4 {
background-color: #cfcfcf;
width: 200px;
height: 200px;
position: absolute;
left: 461px;
top: 147px;
z-index: 100;
}
</style>
</head>
<body>
<div id='div1' onclick='eventc(this)'>
div1
</div>
<div id='div2' onclick='client(this);'>
div2
</div>
<div id='div3' onclick='screen(this);'>
div3
</div>
<div id='div4'onclick='offset(this);'>
offset 控件相对于父窗体的位置
</div>
<script>
function offset(ids) {
ids.innerHTML = "offsetLeft =" + ids.offsetLeft + "<BR>";
ids.innerHTML += "offsetWidth =" + ids.offsetWidth + "<BR>";
ids.innerHTML += "offsetHeight =" + ids.offsetHeight + "<BR>";
ids.innerHTML += "offsetTop =" + ids.offsetTop + "<BR>";
ids.innerHTML += "event.offset 鼠标相对于控件的位置<BR>";
ids.innerHTML += "offsetX =" + event.offsetX + "<BR>";
ids.innerHTML += "offsetY =" + event.offsetY + "<BR>";
}
function screen(ids) {
ids.innerHTML = "scrollWidth =" + ids.scrollWidth + "<BR>";
ids.innerHTML += "scrollHeight =" + ids.scrollHeight + "<BR>";
ids.innerHTML += "scrollTop =" + ids.scrollTop + "<BR>";
ids.innerHTML += "scrollLeft =" + ids.scrollLeft + "<BR>";
}
function client(ids) {
ids.innerHTML = "clientWidth =" + ids.clientWidth + "<BR>";
ids.innerHTML += "clientHeight =" + ids.clientHeight + "<BR>";
ids.innerHTML += "clientTop =" + ids.clientTop + "<BR>";
ids.innerHTML += "clientLeft =" + ids.clientLeft + "<BR>";
}
function eventc(ids) {
ids.innerHTML = "鼠标相对于屏幕坐标<BR>event.screenX=" + event.screenX + "<BR>";
ids.innerHTML += "event.screenY =" + event.screenY + "<BR>";
ids.innerHTML += "鼠标相对于网页坐标event.clientX=" + event.clientX + "<BR>";
ids.innerHTML += "event.clientY =" + event.clientY + "<BR>";
}
</script>
</body>
</html>
运行结果:
以下内容以用自:http://www.funnyhao.com/pagex-clientx-offsetx-layerx-of-those-things/
pageX,clientX,offsetX,layerX的那些事
在各个浏览器的JS中,有很多个让你十分囧的属性,由于各大厂商对标准的解释和执行不一样,导致十分混乱,也让我们这些前端攻城狮十分无语和纠结>_<
John Resig大神说过,动态元素有3个至关重要的元素,位置,尺寸和可见性.所以,今天,先拿几个页面位置属性开刀.
一.PageX和clientX
PageX和clientX ,这个两个比较容易搞混,
PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化
clientX:鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化.
真拗口,直接上图,
两个DIV接触点(黑点位置)
如果将浏览器Y轴方向缩小,出现了滑动条就可以分辨出两者的区别
很明显,红色参考块已经被滑动条截取部分,PageY不变,但是clientY已经变了
可是悲剧的是,PageX只有FF特有,IE这个悲剧没有啊T_T,所以大牛们想出了一个办法
PageY=clientY+scrollTop-clientTop;(只讨论Y轴,X轴同理,下同)
页面上的位置=可视区域位置+页面滚动条切去高度-自身border高度,还是直接上图比较清楚
很明显,模块交界处,scrollTop代表的是被浏览器滑动条滚过的长度,和clientY相加,刚好等于100,最后还要再减去一个clientTop,即是border-top的宽度
Jquery中的PageX的代码如下.十分精炼..
// Calculate pageX/Y if missing and clientX/Y available
if ( event.pageX == null && event.clientX != null ) {
var doc = document.documentElement, body = document.body;
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
}
二.screenX
screenX:鼠标在屏幕上的位置,从屏幕左上角开始,这个没有任何争议,不讨论 ^_^
三.offsetX和layerX
接下来是offsetX和layerX
offsetX:IE特有,鼠标相比较于触发事件的元素的位置,以元素盒子模型的内容区域的左上角为参考点,如果有boder,可能出现负值
IE以内容区域开始,向上进入border将出现负值
layerX:FF特有,鼠标相比较于当前坐标系的位置,即如果触发元素没有设置绝对定位或相对定位,以页面为参考点,如果有,将改变参考坐标系,从触发元素盒子模型的border区域的左上角为参考点
也就是当触发元素设置了相对或者绝对定位后,layerX和offsetX就幸福地生活在一起^-^,几乎相等,唯一不同就是一个从border为参考点,一个以内容为参考点
FF从border开始,
x/y:IE特有,这个本来和layerX/layerY的作用基本一样,但是IE的当前坐标选择十分混乱,能不用就不用,不讨论
网上别人总结的关于这六个纠结的纠结表..
1
2
3
4
5
6
|
offsetX/offsetY:W3C- IE+ Firefox- Opera+ Safari+ chrome+
x/y:W3C- IE+ Firefox- Opera+ Safari+ chrome+
layerX/layerY:W3C- IE- Firefox+ Opera- Safari+ chrome+
pageX/pageY:W3C- IE- Firefox+ Opera+ Safari+ chrome+
clientX/clientY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+
screenX/screenY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ |
只有clientX和screenX 皆大欢喜是W3C标准.其他的,都纠结了.
最给力的是,chrome和safari一条龙通杀!完全支持所有属性.其中(offsetX和layerX都是以border为参考点)...
调式页面连接.
综合event的screenX、clientX、pageX、offsetX(layerX、x)的代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>无标题文档</title>
<style type="text/css">
div {
font-family: "宋体";
font-size: 12px;
color: #000000;
}
* {
padding: 0;
margin: 0
}
#div1 {
position: absolute;
background-color: #f0f0f0;
width: 200px;
height: 300px;
left: 20px;
top: 0px;
z-index: 1;
}
#div2 {
background-color: #cfc0cf;
width: 200px;
height: 210px;
position: absolute;
left: 261px;
top: 347px;
z-index: 100;
}
#div3 {
background-color: #abbfbf;
width: 200px;
height: 200px;
position: absolute;
left: 20px;
top: 347px;
z-index: 100;
}
#div4 {
background-color: #cfcfcf;
width: 200px;
height: 200px;
position: absolute;
left: 461px;
top: 147px;
z-index: 100;
}
</style>
</head>
<body>
<div id='div1' onclick='eventc(this,event)'>
div1
</div>
<div id='div2' onclick='client(this);'>
div2
</div>
<div id='div3' onclick='screen(this);'>
div3
</div>
<div id='div4'onclick='offset(this);'>
offset 控件相对于父窗体的位置
</div>
<script>
function offset(ids) {
ids.innerHTML = "offsetLeft =" + ids.offsetLeft + "<BR>";
ids.innerHTML += "offsetWidth =" + ids.offsetWidth + "<BR>";
ids.innerHTML += "offsetHeight =" + ids.offsetHeight + "<BR>";
ids.innerHTML += "offsetTop =" + ids.offsetTop + "<BR>";
}
function screen(ids) {
ids.innerHTML = "scrollWidth =" + ids.scrollWidth + "<BR>";
ids.innerHTML += "scrollHeight =" + ids.scrollHeight + "<BR>";
ids.innerHTML += "scrollTop =" + ids.scrollTop + "<BR>";
ids.innerHTML += "scrollLeft =" + ids.scrollLeft + "<BR>";
}
function client(ids) {
ids.innerHTML = "clientWidth =" + ids.clientWidth + "<BR>";
ids.innerHTML += "clientHeight =" + ids.clientHeight + "<BR>";
ids.innerHTML += "clientTop =" + ids.clientTop + "<BR>";
ids.innerHTML += "clientLeft =" + ids.clientLeft + "<BR>";
}
function eventc(ids,event) {
event = event?event:window.event ;
ids.innerHTML = "鼠标相对于屏幕坐标<BR>event.screenX=" + event.screenX + "<BR>";
ids.innerHTML += "event.screenY =" + event.screenY + "<BR>";
//从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化
ids.innerHTML += "鼠标在页面上可视区域的位置,<br>"+
"event.clientX=" + event.clientX + "<BR>";
ids.innerHTML += "event.clientY =" + event.clientY + "<BR>";
//IE 特有(比较FF而言)
ids.innerHTML += "类比FF中的event.page鼠标在页面上的位置<BR>";
offsetXFF(ids,event);
ids.innerHTML += "event.offset 鼠标相对于控件的位置<BR>";
ids.innerHTML += "offsetX =" + event.offsetX + "<BR>";
ids.innerHTML += "offsetY =" + event.offsetY + "<BR>";
ids.innerHTML += "event.x,y 鼠标相对于控件的位置(与offset不同点:参考点),不建议使用";
ids.innerHTML += "event.x =" + event.x + "<BR>";
ids.innerHTML += "event.y =" + event.y + "<BR>";
//FF 特有(比较IE而言)
//从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化
ids.innerHTML += "event.page鼠标在页面上的位置<BR>";
ids.innerHTML += "event.pageX =" + event.pageX + "<BR>";
ids.innerHTML += "event.pageY =" + event.pageY + "<BR>";
ids.innerHTML += "event.layerX 鼠标相对于控件的位置(IE中的offset)<BR>";
ids.innerHTML += "layerX =" + event.layerX + "<BR>";
ids.innerHTML += "layerY =" + event.layerY + "<BR>";
}
function offsetXFF(ids,event){
event = event?event:window.event ;
if (event.pageX == null && event.clientX != null ) {
var doc = document.documentElement, body = document.body;
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
ids.innerHTML += "event.pageX =" + event.pageX + "<BR>";
ids.innerHTML += "event.pageY =" + event.pageY + "<BR>";
}
}
</script>
</body>
</html>