72 lines
1.8 KiB
Plaintext
72 lines
1.8 KiB
Plaintext
class DelayedScroll {
|
||
constructor() {
|
||
this.initialized = false;
|
||
this.maxScroll = window.innerHeight * 2; // 最多监听2屏的高度
|
||
this.init();
|
||
}
|
||
|
||
init() {
|
||
if (this.initialized) return;
|
||
|
||
let ticking = false;
|
||
|
||
const handleScroll = () => {
|
||
if (!ticking) {
|
||
requestAnimationFrame(() => {
|
||
const scrollY = window.scrollY;
|
||
|
||
// 只在首屏范围内应用效果
|
||
if (scrollY <= this.maxScroll) {
|
||
this.updateElements(scrollY);
|
||
} else {
|
||
// 超出范围时停止监听
|
||
window.removeEventListener('scroll', scrollHandler);
|
||
this.cleanup();
|
||
}
|
||
|
||
ticking = false;
|
||
});
|
||
ticking = true;
|
||
}
|
||
};
|
||
|
||
// 使用节流的滚动监听
|
||
const scrollHandler = () => {
|
||
if (window.scrollY <= this.maxScroll) {
|
||
handleScroll();
|
||
}
|
||
};
|
||
|
||
window.addEventListener('scroll', scrollHandler, { passive: true });
|
||
|
||
// 初始执行一次
|
||
this.updateElements(window.scrollY);
|
||
|
||
this.initialized = true;
|
||
}
|
||
|
||
updateElements(scrollY) {
|
||
document.querySelectorAll('.delayed-element').forEach(element => {
|
||
const delayFactor = this.getDelayFactor(element);
|
||
const delay = scrollY * delayFactor;
|
||
element.style.setProperty('--scroll-delay', delay);
|
||
});
|
||
}
|
||
|
||
getDelayFactor(element) {
|
||
return parseFloat(
|
||
getComputedStyle(element).getPropertyValue('--delay-factor') || 0.2
|
||
);
|
||
}
|
||
|
||
cleanup() {
|
||
// 可选:移除transform,恢复原状
|
||
document.querySelectorAll('.delayed-element').forEach(element => {
|
||
element.style.removeProperty('--scroll-delay');
|
||
element.style.removeProperty('transform');
|
||
});
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
new DelayedScroll(); |