首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用JavaScript和CSS创建动态高亮导航栏

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

原创
作者头像
qife122
发布2025-09-20 08:28:38
发布2025-09-20 08:28:38
1000
代码可运行
举报
运行总次数:0
代码可运行

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

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

初始标记

假设我们有一个单页面应用,内容变化时页面不会重新加载。起始的HTML和CSS是标准的导航栏,额外包含一个id为#highlight的div元素。我们给第一个导航项添加.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导航项时产生动画效果。让我们为nav元素添加点击事件处理程序:

代码语言:javascript
代码运行次数:0
运行
复制
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获取元素位置和尺寸信息:

代码语言:javascript
代码运行次数:0
运行
复制
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元素:

代码语言: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;
}

使用startViewTransition方法触发过渡:

代码语言:javascript
代码运行次数:0
运行
复制
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');
  });
});

调整视图过渡

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

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

::view-transition-new(highlight) {
  height: 100%;
}

最终代码重构

添加回退支持:

代码语言:javascript
代码运行次数:0
运行
复制
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的"视图过渡:处理宽高比变化"

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用JavaScript和CSS创建"动态高亮"导航栏
    • 初始标记
    • 添加点击事件处理程序
    • 移动高亮功能
    • 使用View Transition API
    • 调整视图过渡
    • 最终代码重构
    • 结论
    • 资源
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档