使用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。