我正在制作滑入式标题的动画。当某个 HTML 元素滚动到页面顶部后,标题应该滑入。当该元素从页面顶部向后滚动时,它应该滑出。我遇到的问题是,当元素到达页面顶部时,两个动画同时发生。
示例位于 https://codepen.io/scottthomason/pen/VwNZVLd。这是后代的代码。确保浏览器输出窗口的大小足够小以允许滚动。
let header = document.querySelector( '.header' );
let trigger = document.querySelector( '.trigger' );
window.addEventListener( 'scroll', function( e ) {
let topPos = trigger.getBoundingClientRect().top;
if ( topPos <= 10 ) {
console.log( 'Fading in, topPos:', topPos );
header.style.animationName = 'fade-in';
} else {
console.log( 'Fading out, topPos:', topPos );
header.style.animationName = 'fade-out';
}
} );
.header {
border: 3px solid green;
color: white;
background-color: red;
padding: 16px;
width: 100%;
position: fixed;
top: -60px;
opacity: 0;
animation-duration: 0.5s;
}
@keyframes fade-in {
from { top: -60px; opacity: 0; }
to { top: 0; opacity: 1; }
}
@keyframes fade-out {
from { top: 0; opacity: 1; }
to { top: -60px; opacity: 0; }
}
<div class="header">
Header goes here.
</div>
<div class="content">
<h1>Content 1</h1>
<h1>Content 2</h1>
<h1 class="trigger">Content 3</h1>
<h1>Content 4</h1>
<h1>Content 5</h1>
<h1>Content 6</h1>
<h1>Content 7</h1>
<h1>Content 8</h1>
</div>
由于动画播放后 header 返回到初始状态而出现的问题。
您可以在标题中使用
transition
属性,并使用 JavaScript 操作 opacity
和 position
,而不是在动画中使用关键帧。
CSS:
.header {
border: 3px solid blue;
color: white;
background-color: red;
padding: 16px;
width: 100%;
position: fixed;
top: -60px;
opacity: 0;
transition: 0.5s ease
}
JS:
let header = document.querySelector( '.header' );
let trigger = document.querySelector( '.trigger' );
window.addEventListener( 'scroll', function( e ) {
let topPos = trigger.getBoundingClientRect().top;
if ( topPos <= 10 ) {
header.style.opacity = '1';
header.style.top = '0';
} else {
header.style.opacity = '0';
header.style.top = '-60px';
}
} );
每当浏览器执行动画时,它都会恢复到之前应用于元素的样式。因此,在您的情况下,它将很好地播放
fade-in
动画,但应用的样式仍然是您的 .header
类中的样式,该类处于隐藏状态。
有不同的方法可以解决这个问题,例如将两种样式分离在不同的类中,并通过 JS 将它们与动画类一起应用,但我建议使用一个单行代码来为您处理这个问题。只需将
animation-fill-mode: forward;
添加到您的 .header
类中,它将通知浏览器保留最后一个关键帧的计算值。
您可以在MDN上找到更多信息。
您可以使用速记动画并使用前进让动画不返回到初始状态
let header = document.querySelector( '.header' );
let trigger = document.querySelector( '.trigger' );
window.addEventListener( 'scroll', function( e ) {
let topPos = trigger.getBoundingClientRect().top;
if ( topPos <= 10) {
console.log( 'Fading in, topPos:', topPos );
header.style.animationName = 'fade-in';
} else {
console.log( 'Fading out, topPos:', topPos );
header.style.animationName = 'fade-out';
}
} );
.header {
border: 3px solid green;
color: white;
background-color: red;
padding: 16px;
width: 100%;
position: fixed;
top: -60px;
opacity: 0;
animation: 0.4s forwards; /*animation shorthand*/
}
@keyframes fade-in {
from { top: -60px; opacity: 0; }
to { top: 0; opacity: 1; }
}
@keyframes fade-out {
from { top: 0; opacity: 1; }
to { top: -60px; opacity: 0; }
}
<div class="header">
Header goes here.
</div>
<div class="content">
<h1>Content 1</h1>
<h1>Content 2</h1>
<h1 class="trigger">Content 3</h1>
<h1>Content 4</h1>
<h1>Content 5</h1>
<h1>Content 6</h1>
<h1>Content 7</h1>
<h1>Content 8</h1>
</div>