getBoundingClientRect
getBoundingClientRect() 是一个用于获取元素位置和尺寸信息的方法。它返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置,其中包含了以下属性:
- x:元素左边界相对于视口的 x 坐标。
- y:元素上边界相对于视口的 y 坐标。
- width:元素的宽度。
- height:元素的高度。
- top:元素上边界相对于视口顶部的距离。
- right:元素右边界相对于视口左侧的距离。
- bottom:元素下边界相对于视口顶部的距离。
- left:元素左边界相对于视口左侧的距离。
1 2 3 4 5 6 7 8 9 10 11
| const box = document.getElementById("box"); const rect = box.getBoundingClientRect();
console.log(rect.x); console.log(rect.y); console.log(rect.width); console.log(rect.height); console.log(rect.top); console.log(rect.right); console.log(rect.bottom); console.log(rect.left);
|
应用场景
这个方法通常用于需要获取元素在视口中的位置和尺寸信息的场景,比如实现拖拽、定位或响应式布局等,兼容性很好,一般用滚动事件比较多。
特殊场景会用上,比如你登录了淘宝的网页,当你下拉滑块的时候,下面的图片不会立即加载出来,有一个懒加载的效果。当上面一张图片没在可视区内时,就开始加载下面的图片。
下面代码就是判断一个容器是否出现在可视窗口内:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const box = document.getElementById("box"); window.onscroll = function () { console.log(checkInView(box)); };
function checkInView(dom) { const { top, left, bottom, right } = dom.getBoundingClientRect(); return ( top > 0 && left > 0 && bottom <= (window.innerHeight || document.documentElement.clientHeight) && right <= (window.innerWidth || document.documentElement.clientWidth) ); }
|
当容器在可视区域内就输出 true
,否则就是 false
。
intersectionObserver
IntersectionObserver
是一个构造函数,可以接收两个参数,第一个参数是一个回调函数,第二个参数是一个对象。这个方法用于观察元素相交情况,它可以异步地监听一个或多个目标元素与其祖先元素或视口之间的交叉状态。它提供了一种有效的方法来检测元素是否可见或进入视口。
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
const observer = new IntersectionObserver(callback, options); const callback = (entries, observer) => { };
const options = { };
const target = document.querySelector("#targetElement"); observer.observe(target);
const callback = (entries, observer) => { entries.forEach((entry) => { if (entry.isIntersecting) { } else { } }); };
|
entries
参数是一个包含每个目标元素交叉状态信息的数组。每个 entry 对象都有以下属性:
target
:观察的目标元素。intersectionRatio
:目标元素与视口的交叉比例,值在 0 到 1 之间。isIntersecting
:目标元素是否与视口相交。intersectionRect
:目标元素与视口的交叉区域的位置和尺寸信息。
options
对象是可选的配置,其中常用的配置选项包括:
root
:指定观察器的根元素,默认为视口。rootMargin
:设置根元素的外边距,用于扩大或缩小交叉区域。threshold
:指定交叉比例的阈值,可以是单个数值或由多个数值组成的数组。
应用场景
IntersectionObserver
适用于实现懒加载、无限滚动、广告展示和可视化统计等场景,同样可以判断元素是否在某一个容器内,不会引起回流。
createNodeIterator
createNodeIterator()
方法是 DOM API 中的一个方法,用于创建一个 NodeIterator 对象,可以用于遍历文档树中的一组 DOM 节点。
通俗一点来讲就是它可以遍历 DOM 结构,把 DOM 变成可遍历的。
应用
遍历 DOM 结构,并且在每个 DOM 节点上都添加了 data-index = "123"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <body> <div id="app"> <p>hello</p> <div class="title">标题</div> <div> <div class="content">内容</div> </div> </div>
<script> const body = document.getElementsByTagName("body")[0]; const item = document.createNodeIterator(body); let root = item.nextNode();
while (root) { console.log(root); if (root.nodeType !== 3) { root.setAttribute("data-index", 123); } root = item.nextNode(); } </script> </body>
|
getComputedStyle
getComputedStyle()
是一个可以获取当前元素所有最终使用的 CSS 属性值的方法。返回的是一个 CSS 样式声明对象。
这个方法有两个参数,第一个参数是你想要获取哪个元素的 CSS ,第二个参数是一个伪元素。
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <style> #box { width: 200px; height: 200px; background-color: cornflowerblue; position: relative; }
#box::after { content: ""; width: 50px; height: 50px; background: #000; position: absolute; top: 0; left: 0; } </style> <body> <div id="box"></div>
<script> const box = document.getElementById("box"); const style = window.getComputedStyle(box, "after");
const height = style.getPropertyValue("height"); const width = style.getPropertyValue("width");
console.log(style); console.log(width, height); </script> </body>
|
requestAnimationFrame
requestAnimationFrame()
是一个用于在下一次浏览器重绘之前调用指定函数的方法,它是 HTML5 提供的 API。
与 setInterval 和 setTimeout
效果对比
设置了两个容器,分别用 requestAnimationFrame()
方法和 setTimeout
方法进行平移效果,用 setTimeout
会有卡顿现象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <style> #box { width: 200px; height: 200px; background-color: cornflowerblue; }
#box2 { width: 200px; height: 200px; background: #000; } </style> <body> <div id="box"></div> <div id="box2"></div>
<script> let distance = 0; let box = document.getElementById("box"); let box2 = document.getElementById("box2");
window.addEventListener("click", function () { requestAnimationFrame(function move() { box.style.transform = `translateX(${distance++}px)`; requestAnimationFrame(move); });
setTimeout(function change() { box2.style.transform = `translateX(${distance++}px)`; setTimeout(change, 17); }, 17); }); </script> </body>
|