雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

js使用IntersectionObserver实现锚点在当前页面视口时导读高亮

2024-11-01 30

在 JavaScript 中可以通过监听页面滚动事件,检查每个锚点的位置,并根据当前滚动位置高亮相应的导航项,从而实现页面内锚点链接的导读高亮效果。

交叉观察器 API(Intersection Observer API)提供了一种异步检测目标元素与祖先元素或顶级文档的视口相交情况变化的方法。

过去,要检测一个元素是否可见或者两个元素是否相交并不容易,很多解决办法不可靠或性能很差。然而,随着互联网的发展,这种需求却与日俱增,比如,下面这些情况都需要用到相交检测:

在页面滚动时“懒加载”图像或其他内容。 实现“无限滚动”网站,在滚动过程中加载和显示越来越多的内容,这样用户就不必翻页了。 报告广告的可见度,以便计算广告收入。 根据用户是否能看到结果来决定是否执行任务或动画进程。

以下是一个示例,展示如何通过 JavaScript 和简单的 CSS 实现这一效果:

1. HTML 结构

假设我们有几个内容段落,每个段落都有一个锚点(即 ID),并且对应一个导航项。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Anchor Navigation Highlight</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>

<div class="navbar">
    <a href="#section1" class="nav-link">Section 1</a>
    <a href="#section2" class="nav-link">Section 2</a>
    <a href="#section3" class="nav-link">Section 3</a>
    <a href="#section4" class="nav-link">Section 4</a>
</div>

<div id="section1" class="section">Content for Section 1</div>
<div id="section2" class="section">Content for Section 2</div>
<div id="section3" class="section">Content for Section 3</div>
<div id="section4" class="section">Content for Section 4</div>

<script src="script.js"></script>
</body>
</html>

2. CSS 样式

定义一个高亮样式来显示当前活动的导航项。

/* styles.css */
body {
    font-family: Arial, sans-serif;
}

.navbar {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #333;
    padding: 10px;
}

.navbar a {
    color: white;
    margin: 0 10px;
    text-decoration: none;
}

.navbar a.active {
    color: yellow;
}

.section {
    padding: 100px 20px;
    margin-top: 50px;
    height: 600px;
    border: 1px solid #ddd;
}

3. JavaScript 实现锚点高亮

通过 Intersection Observer API 检测每个锚点所在的内容块是否在视口中,并在导航栏中高亮相应的链接。

// script.js
document.addEventListener("DOMContentLoaded", function() {
    const sections = document.querySelectorAll(".section");
    const navLinks = document.querySelectorAll(".navbar .nav-link");

    // 创建 Intersection Observer
    const observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            const navLink = document.querySelector(`.navbar a[href="#${entry.target.id}"]`);
            if (entry.isIntersecting) {
                navLinks.forEach(link => link.classList.remove("active"));
                navLink.classList.add("active");
            }
        });
    }, {
        threshold: 0.5  // 在元素50%进入视口时触发
    });

    // 观察每个 section
    sections.forEach(section => observer.observe(section));
});

代码说明

HTML 部分:每个内容区块有一个唯一的 id,用于定位锚点,并在导航栏中设置相应的链接。

CSS 部分:通过 .active 类来标识当前高亮的导航项。

JavaScript 部分:

使用 IntersectionObserver,以便在滚动时检测每个内容区块是否在视口内。

在每个区块达到 50% 可见性时,更新导航栏高亮状态,使得对应的导航链接增加 active 类。

在观察到一个区块进入视口时,将其他链接的 active 类移除,保证只有一个导航项被高亮。

这样就可以实现根据页面滚动自动高亮当前锚点导航的效果。

更新于:20天前
赞一波!

文章评论

评论问答