HTML 部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素滚动动画</title>
<style>
#target {
display: none;
width: 200px;
height: 200px;
background-color: lightblue;
}
</style>
</head>
<body>
<div id="target"></div>
<script src="script.js"></script>
</body>
</html>
JavaScript 部分
window.addEventListener('scroll', function () {
const target = document.getElementById('target');
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
if (scrollTop >= 200) {
target.style.display = 'block';
target.style.animation = 'fadeIn 1s ease-in-out';
} else {
target.style.animation = 'none';
target.style.display = 'none';
}
if (documentHeight - scrollTop - windowHeight <= 300) {
target.style.animation = 'fadeOut 1s ease-in-out';
}
});
// 定义动画关键帧
document.createElement('style').innerHTML = `
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
`;
优化动画性能避免卡顿的方法
- 使用 requestAnimationFrame:如果动画逻辑更复杂,使用
requestAnimationFrame
来控制动画的每一帧,它会在浏览器下一次重绘之前调用回调函数,确保动画与浏览器的刷新频率同步,减少卡顿。例如:
function handleScroll() {
const target = document.getElementById('target');
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;
if (scrollTop >= 200) {
target.style.display = 'block';
requestAnimationFrame(() => {
target.style.animation = 'fadeIn 1s ease-in-out';
});
} else {
target.style.animation = 'none';
target.style.display = 'none';
}
if (documentHeight - scrollTop - windowHeight <= 300) {
requestAnimationFrame(() => {
target.style.animation = 'fadeOut 1s ease-in-out';
});
}
}
window.addEventListener('scroll', handleScroll);
- 减少重排和重绘:尽量避免在动画过程中频繁改变元素的布局属性(如
width
、height
、margin
等),因为这些改变会触发重排和重绘,消耗性能。在上述代码中,通过 display
控制元素显示隐藏,animation
控制动画,减少对布局属性的动态修改。
- 硬件加速:使用
will-change
属性提前告知浏览器元素即将发生变化,让浏览器有机会提前优化。例如:
#target {
will-change: opacity;
}
- 优化 CSS 动画:使用
transform
和 opacity
来实现动画,因为这两个属性触发的是合成层动画,不会触发重排和重绘,性能较好。上述代码中 fadeIn
和 fadeOut
动画使用 opacity
就是基于这个考虑。