锚点定位
1. href
缺点:点击锚点 浏览器url变化
<h2>
<a href="#div1">to div1</a>
<a href="#div2">to div2</a>
<a href="#div3">to div3</a>
</h2>
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
2. window.location.hash方法
缺点:地址变化
3. scrollIntoView方法 推荐
document.getElementById("divId").scrollIntoView();
比如:
document.querySelector("#roll1").onclick = function(){
document.querySelector("#roll1_top").scrollIntoView(true);
}
// 参数 true 元素的顶端将和其所在滚动区的可视区域的顶端对齐。
// 参数 false 元素的底端将和其所在滚动区的可视区域的底端对齐
参数
-
alignToTop(可选)
- 值为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐
- 值为false,元素的底端将和其所在滚动区的可视区域的底端对齐
scrollIntoViewOptions(可选) 该参数为对象形式
behavior(可选):定义动画过渡效果, 值为auto或smooth之一。默认为auto。block(可选):定义垂直方向的对齐, 值为start,center,end, 或nearest之一。默认为start。inline(可选):定义水平方向的对齐, 值为start,center,end, 或nearest之一。默认为nearest。
优点: URL不会变,同时能够响应相应的scroll事件
缺点:
- 兼容性问题 不支持ios(可以使用scrollIntoView结合smoothscroll-polyfill插件实现 ios平滑滚动)
Demo
平滑滚动 CSS属性 scroll-behavior
MDN介绍:当用户手动导航 或者CSSOM scrolling API 出发滚动操作时,scroll- behavior 为一个滚动框指定滚动行为 ,其他滚动不受影响。在根元素中指定这个属性时,它反而适用于视窗。
该属性有2个值可选
- auto : 滚动框立即滚动,即默认效果,没有平滑滚动效果
- smooth : 有平滑滚动效过
缺点:兼容性。不支持IE
例子 新打开一个窗口 查找 或者代码
锚点高亮怎么做?
Intersection Observer
Intersection Observer API 提供了一种异步观察目标元素与祖先元素或顶级文档视口 viewport 的交集变化的方法。 这个API叫做交叉观察器。它常用于追踪一个元素在窗口的可视问题,比如下图,滚动页面,顶部会提示绿色方块的可视性。
使用场景
- 图片懒加载 - 图片滚动到可见时 再加载
- 内容无限滚动
- 检测广告的曝光情况 --为了计算广告收益,需要知道广告元素的曝光情况
- 在用户看见某个区域时。执行任务-或者播放动画
传统位置计算的方式,依赖于对 DOM 状态的轮询计算,然而这种方式会在主线程里密集执行从而造成页面性能问题
getBoundingClientRect() 的频繁调用也可能引发浏览器的样式重计算和布局。如果是在 iframe 里,因为同源策略,我们不能直接访问元素,也就很难用传统方式去处理 iframe 里的元素。
Intersection Observer 的设计,就是为了更方便的处理元素的可视问题。使用 Intersection Observer 我们可以很容易的监控元素进入和离开可视窗口,实现节点的预加载和延迟加载。Intersection Observer 并不是基于像素变化的实时计算,它的反馈会有一定的延时,这种异步的方式减少了对 DOM 和 style 查询的昂贵计算和持续轮询,相比传统方式降低了 CPU、GPU 的消耗。
痛点:
需要频繁使用事件监听,频繁调用,Element.getBoundingClientRect() 方法以获取相关元素的边界信息,在主线程调用,事件会造成性能问题。
假如有一个无限滚动的网页,开发者使用了一个第三方库来管理整个页面的广告,又用了另外一个库来实现消息盒子和点赞,并且页面有很多动画(动画往往意味着较高的性能消耗)。两个库都有自己的相交检测程序,都运行在主线程里,而网站的开发者对这些库的内部实现知之甚少,所以并未意识到有什么问题。但当用户滚动页面时,这些相交检测程序就会在页面滚动回调函数里不停触发调用,造成性能问题,用户体验差。
原理:
注册一个回调函数,每当被监听的元素进入或退出另一个元素时,或者两个元素的相交部分发生变化时,该回调方法会被触发执行。
⚠️注意 Intersection Observer API 无法提供重叠的像素个数或者具体哪个像素重叠,更常见的使用方式是——当两个元素相交比例在 N% 左右时,触发回调,以执行某些逻辑。
一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
概念及用法
概念
- 配置一个回调函数,触发
-
每当目标元素target 与 视窗(或其他指定元素)发生交集的时候执行。
-
Observer 第一次监听目标元素的时候
-
用法
创建一个intersectionObserver对象
创建一个 IntersectionObserver 对象,并传入相应参数和回调用函数,该回调函数将会在目标(target)元素和根(root)元素的交集大小超过阈值(threshold)规定的大小时候被执行。
let options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);
阈值为1.0意味着目标元素完全出现在 root 选项指定的元素中可见时,回调函数将会被执行。
intersectionObserver 对象参数
callback回调函数
当元素可见比例超过指定阈值后,会调用一此回调函数,这个回调函数有两个参数enters和observer
entries: 一个IntersectionObserverEntry对象的数组。
observer: 被调用的IntersectionObserver实例
entries
let callback = (entries, observer) => {
entries.forEach(entry => {
// 每个entry都描述了一个观察到的目标元素交集的变化
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
- boundingClientRect 返回包含目标元素(被检测的元素)的边界信息的
DOMRectReadOnly. 边界的计算方式与Element.getBoundingClientRect()相同.

-
intersectionRatio 返回
intersectionRect与boundingClientRect的比例值.一个介于 0.0 和 1.0 之间的数字,表示在根的相交矩形内实际可见的目标元素有多少。更准确地说,该值是相交矩形 (intersectionRect) 的面积与目标边界矩形 (boundingClientRect) 的面积之比。 -
intersectionRect 目标元素与视口(或根元素)的交叉区域的信息
-
isIntersecting 布尔值
返回一个布尔值, 如果目标元素与交叉区域观察者对象的根相交,则返回 true .不相交返回false
-
rootBounds 返回一个
DOMRectReadOnly用来描述交叉区域观察者(intersection observer)中的根.- 根元素的矩形区域的信息,
getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
- 根元素的矩形区域的信息,
-
target 被检测的元素(目标元素),是一个 DOM 节点对象
-
time。返回一个记录从
IntersectionObserver的时间原点(time origin)到交叉被触发的时间的时间戳
options对象
-
root
-
指定根元素,必须是target元素的父级元素
-
未指定或为
null则默认浏览器视窗 -
顶级文档视窗 viewport
⚠️ 视口当前可见的部分叫做 可视视口 可视视口比布局视口更小,缩小缩放时,布局视口不变,可视视口变小
-
-
rootMargin
- 根元素的外边距 ,可以是百分比
- 用作 root元素和target元素发生交集的区域范围,使用可以控制root元素每一边的收缩和扩张
- 默认0px
-
threshold
-
可以是number。也可以是number Array
-
target 元素和 root 元素相交程度达到该值的时候 IntersectionObserver 注册的回调函数将会被执行。
-
默认值是0 (意味着只要有一个 target 像素出现在 root 元素中,回调函数将会被执行)。
-
该值为1.0含义是当 target 完全出现在 root 元素中时候 回调才会被执行。
-

方法
| 方法 | 说明 |
|---|---|
| observe() | 开始监听一个目标元素 |
| unobserve() | 停止监听特定目标元素 |
| takeRecords() | 返回所有观察目标的IntersectionObserverEntry对象数组 |
| disconnect() | 使IntersectionObserver对象停止全部监听工作 |
// 开始观察
io.observe(document.getElementById('example'));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
兼容性
总结
总体来说IntersectionObserver在检测元素进入视口区域来说提供了极大的便利性。但是在使用的时候需要考虑兼容性(可以使用intersection-observer-polyfill解决)
⚠️建议设置的观察视口是上一级的可滚动的元素,如果root是视口而且上一级有滚动元素的时候会有一些问题