JavaScript如何判断页面元素的上下左右位置信息?
发布于 作者:苏南大叔 来源:程序如此灵动~在上一篇文章里面,苏南大叔描述了如何通过js
获得元素的各种尺寸信息。在本文中,苏南大叔将使用类似的方法,获得页面元素的各种位置信息。其中,位置信息,大多数情况下只有left
和top
的信息,而没有bottom
和right
信息。在css
中使用bottom
和right
进行定位的时候比较少(特例是fixed
的元素)。
大家好,这里是苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。本文描述获得元素位置信息的几种方式。测试环境:谷歌浏览器@111.0.5563.111
。
龙套范例
这里还是先显示一下本文的龙套演员,例子改编自下面几篇文章:
- https://newsn.net/say/js-dom-size.html
- https://newsn.net/say/page-mode.html
- https://newsn.net/say/css-box-sizing.html
<div>盒子模型360*60</div>
<div id="t0" style="right: 2px; bottom: 3px;">fixed的盒子</div>
<div id="t1">t1,border-box</div>
<div id="t2">t2,content-box</div>
<style>
div {
width: 360px !important;
height: 60px !important;
line-height: 60px;
text-align: center;
vertical-align: middle;
margin: 7px;
background-color: blue;
color: #ffffff;
clear: both;
overflow: auto;
}
div#t0 {
position: fixed;
border: 8px solid gray;
}
div#t1 {
box-sizing: border-box;
padding: 15px;
border: 25px solid gray;
}
div#t2 {
box-sizing: content-box;
padding: 15px;
border: 5px solid gray;
}
body {
padding: 20px;
margin: 11px;
}
</style>
这里除了怪异盒子和标准盒子两个,还增加了一个fixed
的盒子,位置在右下角位置。
基础信息
这里依然先列出相关的基础数据:
方法 | t0(fixed) | t1(怪异) | t2(标准) |
---|---|---|---|
getComputedStyle(document.querySelector('#-'), null).margin | 7px | 7px | 7px |
getComputedStyle(document.querySelector('#-'), null).padding | 0px | 15px | 15px |
getComputedStyle(document.querySelector('#-'), null).borderWidth | 8px | 25px | 5px |
同时,本文涉及到了body
的数据:
数据 | 值 |
---|---|
getComputedStyle(document.querySelector('body'), null).margin | 11px |
getComputedStyle(document.querySelector('body'), null).padding | 20px |
.style.top
、.style.bottom
这个.style.
系列,依然是不主动在元素的style
属性里面定义的话,就并不会显示,很好理解。所以理所应当的只有fixed
的盒子被定义了,所以也只有这个盒子有相关信息显示。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
-.style.left | 空 | 空 | 空 |
-.style.top | 空 | 空 | 空 |
-.style.right | 2px | 空 | 空 |
-.style.bottom | 3px | 空 | 空 |
.clientLeft
和.clientTop
没有.clientRight
,没有.clientBottom
。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
-.clientLeft | 8 | 25 | 5 |
-.clientTop | 8 | 25 | 5 |
client
值得是蓝色的区域,它的left
和top
都指的是border
。只不过因为测量的都是左侧或者上方这种单方向的。所以支取一条边的宽度。所以,结论是:
.clientLeft
=.BorderLeftWidth
.clientTop
=.BorderTopWidth
.offsetLeft
和.offsetTop
没有.offsetRight
,没有.offsetBottom
。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
-.offsetLeft | 1038 | 38 | 38 |
-.offsetTop | 343 | 105 | 192 |
这个是灰色区域(蓝色区域的外部灰边框,不包括边框)距离浏览器最最边上的距离。
对于普通的元素,实际上等于 .margin(父辈的border)*N + body.margin + body.padding
对于本文中的fixed
的元素,实际上
.offsetLeft = 总宽度 - getComputedStyle.right-margin。
scrollLeft
和scrollTop
scroll
涉及到了滚动,那么对于overflow:hidden
或者auto
之类的元素才有意义。所以,本文中的例子,请关注overflow:auto
的诡异盒子模型t1
。测试代码前,可以先拖动一下里面的滚动条。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
-.scrollLeft | 0 | 0 | 0 |
-.scrollTop | 0 | 40 | 0 |
getComputedStyle(document.querySelector('#-'), null).left
方法 | t0(fixed) | t1(怪异) | t2(标准) |
---|---|---|---|
getComputedStyle(document.querySelector('#-'), null).left | 1031px | auto | auto |
getComputedStyle(document.querySelector('#-'), null).top | 336px | auto | auto |
getComputedStyle(document.querySelector('#-'), null).right | 2px | auto | auto |
getComputedStyle(document.querySelector('#-'), null).bottom | 3px | auto | auto |
很明显,这个测试值只有fixed
盒子有意义,其它的盒子取值都是auto
。而且这个取值和对应的offsetLeft
差值就是个单边margin
。offsetLeft
包含左侧的border
,getComputedStyle().left
不包含左侧的margin
。
jq.offset().left
和jq.offset().top
jq.offset().left
取值完全等于.offsetLeft
。没有jq.offset().right
,没有jq.offset().bottom
。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
jq.offset().left | 1038 | 38 | 38 |
jq.offset().top | 343 | 105 | 192 |
这个是灰色区域(蓝色区域的外部灰边框左上角)距离浏览器最最边上的距离。
对于普通的元素,实际上等于 .margin(父辈的border)*N + body.margin + body.padding
对于本文中的fixed
的元素,实际上
.offsetLeft = 总宽度 - getComputedStyle.right-margin。
jq.position().left
和jq.position().top
没有jq.position().right
,没有jq.position().bottom
。
方法 | t0(fixed) | t1(怪异盒子) | t2(标准盒子) |
---|---|---|---|
jq.position().left | 1031 | 31 | 31 |
jq.position().top | 336 | 98 | 185 |
- 和
jq.offset().left
和jq.offset().top
对比的话,就差个对应的单边margin
。 jq.position()
包含margin
在范围内,而jq.offset()
不包含margin
在范围内。
测试代码
本文测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>盒子模型360*60</div>
<div id="t0" style="right: 2px; bottom: 3px">fixed的盒子</div>
<div id="t1">t1,border-box</div>
<div id="t2">t2,content-box</div>
<style>
div {
width: 360px !important;
height: 60px !important;
line-height: 60px;
text-align: center;
vertical-align: middle;
margin: 7px;
background-color: blue;
color: #ffffff;
clear: both;
overflow: auto;
}
div#t0 {
position: fixed;
border: 8px solid gray;
}
div#t1 {
box-sizing: border-box;
padding: 15px;
border: 25px solid gray;
}
div#t2 {
box-sizing: content-box;
padding: 15px;
border: 5px solid gray;
}
body {
padding: 20px;
margin: 11px;
}
</style>
<button onclick="javascript:check()">检测一下</button>
<table>
<tr>
<th>方法</th>
<th>t0</th>
<th>t1</th>
<th>t2</th>
</tr>
</table>
<style>
table {
width: 100%;
border-collapse: collapse;
margin: 0 auto;
text-align: center;
}
table td,
table th {
border: 1px solid #cad9ea;
color: #666;
height: 30px;
}
table th {
background-color: #cce8eb;
width: 100px;
}
table tr:nth-child(odd) {
background: #fff;
}
table tr:nth-child(even) {
background: #f5fafa;
}
</style>
<script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
<script>
function check() {
var tabObj = document.getElementsByTagName("table")[0]; //获取添加数据的表格
var rowsNum = tabObj.rows.length; //获取当前行数
// var colsNum = tabObj.rows[rowsNum - 1].cells.length; //获取行的列数
var infos = [
"getComputedStyle(document.querySelector('#obj'), null).margin",
"getComputedStyle(document.querySelector('#obj'), null).padding",
"getComputedStyle(document.querySelector('#obj'), null).borderWidth",
"obj.style.left",
"obj.style.top",
"obj.style.right",
"obj.style.bottom",
"obj.clientLeft",
"obj.clientTop",
// "obj.clientRight",
// "obj.clientBottom",
"obj.offsetLeft",
"obj.offsetTop",
// "obj.offsetRight",
// "obj.offsetBottom",
"obj.scrollLeft",
"obj.scrollTop",
// "obj.scrollRight",
// "obj.scrollBottom",
"getComputedStyle(document.querySelector('#obj'), null).left",
"getComputedStyle(document.querySelector('#obj'), null).top",
"getComputedStyle(document.querySelector('#obj'), null).right",
"getComputedStyle(document.querySelector('#obj'), null).bottom",
// "getComputedStyle(document.querySelector('#obj'), null).clientLeft",
// "getComputedStyle(document.querySelector('#obj'), null).clientTop",
// "getComputedStyle(document.querySelector('#obj'), null).offsetLeft",
// "getComputedStyle(document.querySelector('#obj'), null).offsetTop",
"$('#obj').offset().left",
"$('#obj').offset().top",
"$('#obj').position().left",
"$('#obj').position().top",
// "$('#obj').position().right",
// "$('#obj').position().bottom",
// "$('#obj').offset().right",
// "$('#obj').offset().bottom",
// "$('#obj').client().left",
// "$('#obj').client().top",
// "$('#obj').scroll().left",
// "$('#obj').scroll().top",
];
var objs = ["t0", "t1", "t2"];
for (var j = 0; j < infos.length; j++) {
var addRow = tabObj.insertRow(rowsNum);
var addRow0 = addRow.insertCell(0);
var js = infos[j].replace("obj", "-");
addRow0.innerHTML = js;
// console.log(js);
for (var i = 0; i < objs.length; i++) {
var addRow1 = addRow.insertCell(i + 1);
var js2 = infos[j].replace("obj", objs[i]);
addRow1.innerHTML = new Function("return " + js2)();
}
rowsNum++;
}
}
</script>
</body>
</html>
相关文章
总结
更多苏南大叔写的js
相关经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。