站长资源网络编程
JavaScript 空间坐标的使用
基础知识
首先参考画布分为视口(窗口)与文档的含义
网页很多都是多屏,所以文档尺寸一般大于视口尺寸
视口尺寸不包括浏览器工具条、菜单、标签、状态栏等
当打开控制台后,视口尺寸相应变小
文档像 position 定位,视口类似 fixed 定位
文档坐标在页面滚动时不发生改变
视口坐标的操作需要考虑滚动条的位置
视口文档
视口坐标需要知道滚动条位置才可以进行计算,有以下几种方式获取滚动位置
方法 说明 注意 window.innerWidth 视口宽度 包括滚动条(不常用) window.innerHeight 视口高度 包括滚动条(不常用) document.documentElement.clientWidth 视口宽度 document.documentElement.clientHeight 视口高度
注意,均是以像素为单位,且视口尺寸不包括浏览器工具条、菜单、标签、状态栏等
<script> document.write(document.documentElement.clientWidth); // 1707 document.write(document.documentElement.clientHeight) // 803 </script>
几何形状
元素在页面中拥有多个描述几何数值的尺寸,下面截图进行了形象的描述。
方法
说明
备注
element.getBoundingClientRect
返回元素在视口坐标及元素大小,不包括外边距,width/height与offsetWidth/offsetHeight匹配
窗口坐标
element.getClientRects
行级元素每行尺寸位置组成的数组
element.offsetParent
拥有定位属性的父级,或body/td/th/table
对于隐藏元素/body/html值为null
element.offsetWidth
元素宽度尺寸,包括内边距与边框和滚动条
element.offsetHeight
元素高度尺寸,包括内边距与边框和滚动条
element.offsetLeft
相对于祖先元素的X轴坐标
element.offsetTop
相对于祖先元素的Y轴坐标
element.clientWidth
元素宽度,不包含边框,只包含内容和内边距,行元素尺寸为0
element.clientHeight
元素高度,不包含边框,只包含内容和内边距,行元素尺寸为0
element.clientLeft
内容距离外部的距离,滚动条在左侧时包括滚动条尺寸
element.clientTop
内容距离顶部的距离,滚动条在顶部时包括滚动条尺寸
element.scrollWidth
元素宽度,内容+内边距+内容溢出的尺寸
element.scrollHeight
元素高度,内容+内边距+内容溢出的尺寸
element.scrollLeft
水平滚动条左侧已经滚动的宽度
element.scrollTop
垂直滚动条顶部已经滚动的高度
为什么不要使用getComputedStyle
尺寸设置 auto 时获取结果不可用
由于滚动条的存在,不同浏览器返回结果不同
元素没有设置尺寸获取不到
getBoundingClientRect
使用 getBoundingClientRect 获取元素矩形信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 300px;
width: 300px;
padding:10px;
margin: 10px;
border:5px solid #ddd;
overflow: hidden;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
let div = document.querySelector("div");
let position = div.getBoundingClientRect();
console.log(position);
</script>
</html>
计算结果的矩形尺寸不包括外边距
bottom: 340
height: 330
left: 18
right: 348
top: 10
width: 330
x: 18
y: 10
getClientRects
多行元素分别返回每行所占的尺寸,下面的行元素将为每行返回矩形尺寸
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
span {
width: 200px;
overflow: auto;
}
</style>
</head>
<span>网页很多都是多屏,所以文档尺寸一般大于视口尺寸,当打开控制台后,视口尺寸相应变小。网页很多都是多屏,所以文档尺寸一般大于视口尺寸,当打开控制台后,视口尺寸相应变小。网页很多都是多屏,所以文档尺寸一般大于视口尺寸,当打开控制台后,视口尺寸相应变小。</span>
<script>
let span = document.querySelector('span')
let info = span.getClientRects()
console.log(info)
</script>
</html>
// 第一行信息
bottom: 29.33333396911621
height: 21.33333396911621
left: 8
right: 1683.5555419921875
top: 8
width: 1675.5555419921875
x: 8
y: 8// 第二行信息
bottom: 50.66666793823242
height: 21.33333396911621
left: 8
right: 264
top: 29.33333396911621
width: 256
x: 8
y: 29.33333396911621
坐标判断
Js 提供了方法获取指定坐标上的元素,如果指定坐标点在视口外,返回值为 null
坐标都是从左上角计算,这与 CSS 中的 right/bottom 等不同
窗口坐标类似于 position:fixed
文档坐标类似于 position:absolute
方法
说明
element.elementsFromPoint
返回指定坐标点所在的元素集合
element.elementFromPoint
返回指定坐标点最顶级的元素
元素集合
返回指定坐标点上的元素集合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
let positionEleList = document.elementsFromPoint(100,100);
console.log(positionEleList);
// div
// body
// html
</script>
</html>
顶级元素
返回坐标点上的顶级元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
let positionEle = document.elementFromPoint(100,100);
console.log(positionEle);
// div
</script>
</html>
滚动控制
方法
说明
参数说明
window.pageXOffset
文档相对窗口水平滚动的像素距离
window.pageYOffset
文档相对窗口垂直滚动的像素距离
element.scrollLeft()
元素X轴滚动位置
element.scrollTop()
元素Y轴滚动位置
element.scrollBy()
按偏移量进行滚动内容
参数为对象,{top:垂直偏移量,left:水平偏移量,behavior:'滚动方式'}
element.scroll() 或 element.scrollTo()
滚动到指定的具体位置
参数为对象,{top:X轴文档位置,left:Y轴文档位置,behavior:'滚动方式'}
element.scrollLeft
获取和设置元素X轴滚动位置
这是属性,设置X轴文档位置
element.scrollTop
获取和设置元素Y轴滚动位置
这是属性,设置Y轴文档位置
element.scrollIntoView(bool)
定位到顶部或底部
参数为true元素定位到顶部,为false定位到窗口底部
使用 scrollBy 滚动文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 2000px;
background: linear-gradient(to bottom, red, green, blue, yellow)
}
</style>
</head>
<body>
</body>
<script>
setInterval(() => {
document.documentElement.scrollBy({top:30,behavior:"smooth"},100); // 相当于每个3秒往下走30px,参照于上次所停留位置,smooth平滑滚动
},3000);
</script>
</html>
使用 scroll 滚动到指定位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 2000px;
background: linear-gradient(to bottom, red, green, blue, yellow)
}
</style>
</head>
<body>
</body>
<script>
setInterval(() => {
document.documentElement.scroll({top:30,behavior:"smooth"},100);
},3000); // 按照绝对位置,距离上部30px,只走一次,smooth平滑滚动
</script>
</html>
使用元素 scrollIntoView 方法实现滚动操作,参数可以是布尔值或对象。
与 <a> 标签锚点效果类似。
参数为 true 时顶部对齐,相当于 {block: "start"}
参数为 false 时底部对齐,相当于 {block: "end"}
定义 {behavior:smooth} 为平滑滚动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
section {
height: 2000px;
background: linear-gradient(to bottom, red, green, blue, yellow)
}
body button {
position: fixed;
bottom: 10%;
width: 100px;
height: 30px;
}
body button:first-of-type {
right: 5%;
}
body button:last-of-type {
left: 5%;
}
</style>
</head>
<body>
<header>
<h1>头部</h1>
</header>
<button class="top">TOP</button>
<button class="bottom">BOTTOM</button>
<section></section>
<footer>
<h1>底部</h1>
</footer>
</body>
<script>
document.querySelector("button.top").addEventListener("click", (event) => {
let h1 = document.querySelector("header h1");
h1.scrollIntoView({
behavior: "smooth",
})
});
document.querySelector("button.bottom").addEventListener("click", (event) => {
let h1 = document.querySelector("footer h1");
h1.scrollIntoView({
behavior: "smooth",
})
})
</script>
</html>

