HTML元素坐标定位,这些知识点得掌握
文档坐标和视口坐标
视口坐标是相对于窗口的坐标,而文档坐标是相对于整个文档而言。例如,在文档坐标中如果一个元素的相对于文档的Y坐标是200px,并且用户已经把浏览器向下滚动了75px,那么视口坐标中元素的Y坐标为200px – 75px = 125px。
如何获取浏览器滚动条的位置?Window对象的pageXOffset和pageYOffset属性在所有浏览器中提供这些值,除IE8以及更早的版本。IE和所有现代浏览器也可以通过scrollLeft和scrollTop属性获取滚动条位置。
下面代码的getScrollOffsets方法获取滚动条位置:
//以一个对象的x和y属性放回滚动条的位置
function getScrollOffsets(w){
w = w || window;
//除了IE 8以及更早的版本以外,其他浏览器都支持
if(w.pageXOffset != null) return {x: w.pageXOffset, y: w.pageYOffset};
//对标准模式下的IE
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop};
//对怪异模式下的浏览器
return { x: d.body.scrollLeft, y: d.body.scrollTop};
}
有时候能够判定视口的尺寸也是非常有用的,下面的代码简便地查询视口尺寸:
//作为一个对象的w和h属性返回视口的尺寸
function getViewportSize(w){
//使用指定的窗口, 如果不带参数则使用当前窗口
w = w || window; //除了IE8及更早的版本以外,其他浏览器都能用
if(w.innerWidth != null)
return {w: w.innerWidth, h: w.innerHeight}; //对标准模式下的IE(或任意浏览器)
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight}; //对怪异模式下的浏览器
return {w: d.body.clientWidth, h: d.body.clientHeight};
}
上面的两个例子已经使用到scrollLeft、scrollTop、clientWidth、clientHeight。 scrollLeft和scrollTop获取滚动条位置,而clientWidth和clientHeight获取对象的尺寸。
查询元素的几何尺寸
判定一个元素的尺寸和位置最简单的方法是调用它的getBoundingClientRect()方法。该方法是在IE5中引入的,而现在当前的所有浏览器都实现了。它不需要参数,返回left、right、top、bottom属性的对象。
这个方法返回元素在视口坐标中的位置。为了转换为甚至用户滚动浏览器窗口以后任然有效的文档坐标,需要加上滚动偏移量:
//元素相对于文档的坐标位置
function getElementRect(e){
var box = e.getBoundingClientRect();
var offsets = getScrollOffsets();
var x = box.left + offsets.x;
var y = box.top + offsets.y; return {x:x, y: y};
}
在很多浏览器中,getBoundingClientRect()返回的对象还包括width和height属性。但在原始的IE中未实现。可以这样计算元素的width和height:
//元素尺寸
function getElementSize(e){
var box = getElementRect(e);
var w = box.width || box.right - box.left;
var h = box.height || box.bottom - box.top; return {w: w, h: h};
}
滚动元素
之前的getScrollOffsets方法可以查询滚动条的位置。该例子的scrollLeft和scrollTop属性可以用来设置让浏览器滚动,但有一种更简单的方法从Javascript最早时期开始支持的。Window对象的scrollTop()方法接口一个点的X和Y坐标(文档坐标),并作为滚动条的偏移量设置它们。下面代码滚动浏览器到文档最下面的页面可见:
//滚动到浏览器最底部
function scrollToBottom(){
//获取文档和视口的高度
var documentHeight = document.documentElement.offsetHeight;
var viewportHeight = window.innerHeight; //或使用上面的getViewPortSize()方法 //然后,滚动让最后一页在视口中可见
window.scrollTo(0, documentHeight - viewportHeight);
}
Window的scrollBy方法和scroll()和scrollTo()类似,但是它的参数是相对的,并在当前滚动条的偏移量上增加。例如,快速阅读者可能会喜欢这样:
javascript:void setInterval(function(){scrollBy(0, 10)}, 200);
如果想让某个元素在文档中可见,可以利用getBoundingClientRect()计算元素的位置,并转换为文档坐标,然后使用scrollTo()方法达到目的。但在需要显示Html元素上调用scrollIntoView()方法更方便。
scrollIntoView()的行为与设置window.location.hash为一个命名锚点的名字后浏览器产生的行为类似。
元素尺寸、位置和溢出
任何HTML元素的只读属性offsetWidth和offsetHeight以CSS像素返回它的屏幕尺寸。返回的尺寸包含元素的边框和内边距,除去了外边距。
所有HTML元素拥有offsetLeft和offsetTop属性来返回元素的X和Y坐标。这些值是文档坐标,并直接指定元素的位置。当对于已定位元素的后代元素和一些其他元素,这些属性返回的坐标是相对于祖先元素的而非文档。
offsetParent属性指定这些属性所相对的父元素。如果offsetParent为null,这些属性都是文档坐标,因此,一般来说,用offsetLeft和offsetTop来计算元素e的位置需要一个循环:
//计算元素位置
function getElementPosition(e){
var x = 0, y = 0;
while(e != null){
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
} return {x: x, y: y };
}
getElementPosition函数也不总是计算正确的值,下面看如何修复它。除了这些名字以offset开头的属性以外,所有的文档元素定义了其他两组属性,名字一组以client开头,另一组以scroll开头。即每个元素都有以下这些属性:
|
offsetWidth |
clientWidth | scrollWidth |
| offsetHeight | clientHeight | crollHeight |
| offsetLeft | clientLeft | scrollLeft |
| offsetTop | clientTop | scrollTop |
| offsetParent |
为了理解client和scroll属性,你需要知道元素的实际内容可能比分配用来容纳的盒子更大,因此单个元素可能有滚动条。内容区域是视口,就像浏览器窗口,当实际内容比视口大,需要把元素滚动套位置考虑进去。
clientWidth和clientHeight类似offsetWidth和offsetHeight,区别在于它们不包含边框大小。只包含内容和内边距。同时,如果浏览器在内边距和边框之间添加了滚动条,clientWidth和clientHeight不包含滚动条尺寸。在文档的根元素上查询这些属性时,它们的返回值和窗口的innerWidth和innerHeight属性值相等。
clientLeft和clientTop属性没什么用:它们返回元素的内边距的外边框和它的边框的外边缘之间的水平距离和垂直距离。
scrollWidth和scrollHeight是元素的内容区域加上它的内边距再加上任何溢出内容的尺寸。当内容正好和内容区域匹配没溢出时,这些属性与clientWidth和clientHeight相等。有溢出时,包含了溢出的内容尺寸。
scollLeft和scrollTop指定元素滚动条的位置。在getScrollOffsets()方法中查询过它们。注意,scrollLeft和scrollTop是可写的,通过设置它们来让元素中的内容滚动(HTML元素并没有类似Window对象的scrollTo()方法。
DEMO
下面代码介绍了前面几个函数的使用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
//以一个对象的x和y属性放回滚动条的位置
function getScrollOffsets(w){
w = w || window;
//除了IE 8以及更早的版本以外,其他浏览器都支持
if(w.pageXOffset != null) return {x: w.pageXOffset, y: w.pageYOffset};
//对标准模式下的IE
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop};
//对冠以模式下的浏览器
return { x: d.body.scrollLeft, y: d.body.scrollTop};
} //作为一个对象的w和h属性返回视口的尺寸
function getViewportSize(w){
//使用指定的窗口, 如果不带参数则使用当前窗口
w = w || window; //除了IE8及更早的版本以外,其他浏览器都能用
if(w.innerWidth != null)
return {w: w.innerWidth, h: w.innerHeight}; //对标准模式下的IE(或任意浏览器)
var d = w.document;
if(document.compatMode == "CSS1Compat")
return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight}; //对怪异模式下的浏览器
return {w: d.body.clientWidth, h: d.body.clientHeight};
} //元素相对于文档的坐标位置
function getElementRect(e){
var box = e.getBoundingClientRect();
var offsets = getScrollOffsets();
var x = box.left + offsets.x;
var y = box.top + offsets.y; return {x:x, y: y};
} //元素尺寸
function getElementSize(e){
var box = getElementRect(e);
var w = box.width || box.right - box.left;
var h = box.height || box.bottom - box.top; return {w: w, h: h};
} //滚动到浏览器最底部
function scrollToBottom(){
//获取文档和视口的高度
var documentHeight = document.documentElement.offsetHeight;
var viewportHeight = window.innerHeight; //或使用上面的getViewPortSize()方法 //然后,滚动让最后一页在视口中可见
window.scrollTo(0, documentHeight - viewportHeight);
} //计算元素位置
function getElementPosition(e){
var x = 0, y = 0;
while(e != null){
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
} return {x: x, y: y };
}
</script>
</head>
<body>
<button id="scrolltoBottomBtn">滚动到浏览器</button>
<div style="height: 400px; background: red;"> </div>
<button id="btn">获取滚动条位置</button>
<button id="viewportBtn">获取视口尺寸</button>
<button id="eleRectBtn">元素文档坐标</button>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.onclick = function(event){
console.log(getScrollOffsets());
} var viewportBtn = document.getElementById("viewportBtn");
viewportBtn.onclick = function(event){
console.log(getViewportSize());
} var eleRectBtn = document.getElementById("eleRectBtn");
eleRectBtn.onclick = function(eevent){
console.log(getElementRect(this));
} var scrolltoBottomBtn = document.getElementById("scrolltoBottomBtn");
scrolltoBottomBtn.onclick = function(){
scrollToBottom();
}
</script>
</body>
</html>
如果本篇内容对大家有帮助,请点击页面右下角的关注。如果觉得不好,也欢迎拍砖。你们的评价就是博主的动力!下篇内容,敬请期待!
HTML元素坐标定位,这些知识点得掌握的更多相关文章
- selenium使用location定位元素坐标偏差
python+selenium+Chromedriver使用location定位元素坐标偏差使用xpath定位元素,用.location获取坐标值,截取网页截图的一部分出现偏差. 之所以会出现这个坐标 ...
- Appium元素定位难点:tap坐标定位不准确
tap用法 1.tap是模拟手指点击页面上元素语法有两个参数,第一个是positions,是list类型最多五个点,duration是持续时间,单位毫秒 tap(self, positions, du ...
- Python+Appium自动化测试(12)-通过坐标定位元素
在使用appium做app自动化测试的过程中,可能会遇到元素的属性值不是唯一的情况,导致不能通过find_element_bi_xx()方法定位元素,这个时候我们就可以通过坐标来定位元素. 1,通过绝 ...
- Appium python自动化测试系列之元素的定位(六)
6.1 常用定位方法讲解 对象定位是自动化测试中很关键的一步,也可以说是最关键的一步,毕竟你对象都没定位那么你想操作也不行.所以本章节的知识我希望大家多动手去操作,不要仅仅只是书本上的知识,毕竟这个 ...
- js随笔,css和js禁止网页选择文本,table的class样式使得td的class样式失效,jquery获得元素坐标
css使用user-select,user-select不是W3C标准,浏览器支持不完整:user-select有两个值,none用户不可以选择文本,text用户可以选择文本 body{-moz-us ...
- appium元素集合定位
概念:某一类型元素的集合 list对象 来源:-控件复用 -相同的控件类型 -取名重复 语法:driver.findElements(By.id("text1")).get(0) ...
- JavaScript通过ID获取元素坐标
JavaScript通过ID获取元素坐标 function getElementPos(elementId) { var ua = navigator.userAgent.toLowerCase ...
- jquery获取当前元素坐标
1. jquery获取当前元素坐标 A) 获取对象
- Css元素布局定位
<!DOCTYPE HTML> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...
随机推荐
- adb devices出现no permissions
在做Android开发的时候,有些设备插入USB调试线,无法调试,出现以下错误: joey 09:58 $ adb devices List of devices attached 20080411 ...
- APP漏洞扫描器之本地拒绝服务检测详解
APP漏洞扫描器之本地拒绝服务检测详解 阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面.本文将讲一下应用漏洞 ...
- ABP理论学习之NHibernate集成
返回总目录 本篇目录 Nuget包 配置 实体映射 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了NHibernate集成.这篇文章会解释如何在A ...
- Silverlight及WPF中实现自定义BusyIndicator
在开发Silverlight或者WPF项目时,当我们调用Web服务来加载一些数据时,由于数据量比较大需要较长的时间,需要用户等待,为了给用户友好的提示和避免用户在加载数据过程中进行重复操作,我们通常使 ...
- Android 两个activity生命周期的关系
Acitivity的生命周期想必大家都清楚,但是两个activity之间其实不是独立各自进行的. 从第一个activity1启动另外一个activity2时,会先调用本activity1的onPaus ...
- ASP.NET MVC 控制器激活(三)
ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControllerInstanc ...
- 《Entity Framework 6 Recipes》中文翻译系列 (31) ------ 第六章 继承与建模高级应用之自引用关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-4 使用TPH建模自引用关系 问题 你有一张自引用的表,它代表数据库上不同类型 ...
- Tomcat的目录结构
bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat6.exe.tomcat6w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口启动T ...
- 蓄水池(Reservoir_sampling)抽样算法简记
摘要 1.适用场合 2.算法简介 3.代码例子 4.Spark RangePartitioner 中的应用(待补充) 内容 1.适用场合:从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数 ...
- 面向属性的CSS命名
自从开始做前端开发以来,我发现在开发页面的时候,总是有一个问题十分影响自己的开发效率,这个问题就是css的命名,主要是指css类选择器的命名.这个问题主要体现在:第一,有的内容你压根想不出用什么名字来 ...