使用JavaScript与CSS创建"移动高亮"导航栏

使用JavaScript与CSS创建"移动高亮"导航栏

在本教程中,Blake Lundquist向我们展示了两种仅使用原生JavaScript和CSS创建"移动高亮"导航模式的技巧。第一种技术使用getBoundingClientRect方法在点击时显式动画导航栏项之间的边框。第二种方法使用新的View Transition API实现相同功能。

初始标记

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

html 复制代码
<nav>
  <div id="highlight"></div>
  <a href="#" class="active">Home</a>
  <a href="#services">Services</a>
  <a href="#about">About</a>
  <a href="#contact">Contact</a>
</nav>

方法一:使用getBoundingClientRect

我们通过绝对定位#highlight元素在.active类元素周围创建边框,并添加过渡样式使元素位置和大小变化时产生渐变效果。

css 复制代码
#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导航项时动画高亮元素:

javascript 复制代码
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');
  moveHighlight();
});

使用getBoundingClientRect计算高亮元素的新位置和宽度:

javascript 复制代码
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

View Transition API提供了在网站视图之间创建动画过渡的功能。我们不再需要单独的#highlight元素,而是直接使用伪选择器样式.active导航项,让API处理UI状态变化时的动画。

css 复制代码
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;
}

触发过渡的JavaScript代码:

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

资源

相关推荐
墨染天姬25 分钟前
【AI】端侧AIBOX可以部署哪些智能体
人工智能
AI成长日志29 分钟前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
SharpCJ34 分钟前
Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革
android·ai·aigc
2501_9481142441 分钟前
2026年大模型API聚合平台技术评测:企业级接入层的治理演进与星链4SAPI架构观察
大数据·人工智能·gpt·架构·claude
小小工匠43 分钟前
LLM - awesome-design-md 从 DESIGN.md 到“可对话的设计系统”:用纯文本驱动 AI 生成一致 UI 的新范式
人工智能·ui
黎阳之光1 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
小超同学你好1 小时前
面向 LLM 的程序设计 6:Tool Calling 的完整生命周期——从定义、决策、执行到观测回注
人工智能·语言模型
墨风如雪1 小时前
玩转本地 AI 的“第 0 步”:Node.js 环境保姆级安装教程
aigc
智星云算力1 小时前
本地GPU与租用GPU混合部署:混合算力架构搭建指南
人工智能·架构·gpu算力·智星云·gpu租用
jinanwuhuaguo2 小时前
截止到4月8日,OpenClaw 2026年4月更新深度解读剖析:从“能力回归”到“信任内建”的范式跃迁
android·开发语言·人工智能·深度学习·kotlin