写点什么

使用 JavaScript 和 CSS 创建动态高亮导航栏

作者:qife122
  • 2025-09-20
    福建
  • 本文字数:1602 字

    阅读完需:约 5 分钟

使用 JavaScript 和 CSS 创建"动态高亮"导航栏

在本教程中,Blake Lundquist 将带领我们使用纯 JavaScript 和 CSS 实现"动态高亮"导航模式的两种方法。第一种技术使用 getBoundingClientRect 方法,在导航栏项目被点击时显式地动画化边框。第二种方法使用新的 View Transition API 实现相同的功能。

初始标记

假设我们有一个单页面应用,内容变化时页面不会重新加载。起始的 HTML 和 CSS 是标准的导航栏,额外包含一个 id 为 #highlight 的 div 元素。我们给第一个导航项添加.active 类。


#highlight {  z-index: 0;  position: absolute;  height: 100%;  width: 100px;  left: -200px;  border: 2px solid green;  box-sizing: border-box;  transition: all 0.2s ease;}
复制代码

添加点击事件处理程序

我们希望高亮元素在用户更改.active 导航项时产生动画效果。让我们为 nav 元素添加点击事件处理程序:


const navbar = document.querySelector('nav');
navbar.addEventListener('click', function (event) { if (!event.target.matches('nav a:not(active)')) { return; } document.querySelector('nav a.active').classList.remove('active'); event.target.classList.add('active');});
复制代码

移动高亮功能

使用 getBoundingClientRect 获取元素位置和尺寸信息:


const moveHighlight = () => {  const activeNavItem = document.querySelector('a.active');  const highlighterElement = document.querySelector('#highlight');    const width = activeNavItem.offsetWidth;  const itemPos = activeNavItem.getBoundingClientRect();  const navbarPos = navbar.getBoundingClientRect()  const relativePosX = itemPos.left - navbarPos.left;
const styles = { left: `${relativePosX}px`, width: `${width}px`, };
Object.assign(highlighterElement.style, styles);}
复制代码

使用 View Transition API

对于这种方法,我们不再需要单独的 #highlight 元素:


nav a::after {  content: " ";  position: absolute;  left: 0;  top: 0;  width: 100%;  height: 100%;  border: none;  box-sizing: border-box;}
nav a.active::after { border: 2px solid green; view-transition-name: highlight;}
复制代码


使用 startViewTransition 方法触发过渡:


navbar.addEventListener('click', async function (event) {  if (!event.target.matches('nav a:not(.active)')) {    return;  }
document.startViewTransition(() => { document.querySelector('nav a.active').classList.remove('active'); event.target.classList.add('active'); });});
复制代码

调整视图过渡

为了解决尺寸不一致问题:


::view-transition-old(highlight) {  height: 100%;}
::view-transition-new(highlight) { height: 100%;}
复制代码

最终代码重构

添加回退支持:


const setActiveElement = (elem) => {  document.querySelector('nav a.active').classList.remove('active');  elem.classList.add('active');}
navbar.addEventListener('click', async function (event) { if (!event.target.matches('nav a:not(.active)')) { return; }
if (!document.startViewTransition) { setActiveElement(event.target); return; } document.startViewTransition(() => setActiveElement(event.target));});
复制代码

结论

网站 UI 状态之间的动画和过渡曾经需要大量外部库和复杂代码,但现在 vanilla JavaScript 和 CSS 已经包含了实现类原生应用交互的功能。我们通过两种方法演示了这一点:使用 CSS 过渡结合 getBoundingClientRect()方法,以及使用 View Transition API。

资源

  • getBoundingClientRect()方法文档

  • View Transition API 文档

  • Jake Archibald 的"视图过渡:处理宽高比变化"更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)公众号二维码

  • 办公AI智能小助手
用户头像

qife122

关注

还未添加个人签名 2021-05-19 加入

还未添加个人简介

评论

发布
暂无评论
使用JavaScript和CSS创建动态高亮导航栏_JavaScript_qife122_InfoQ写作社区