背景 DIV 根据交叉观察器淡入和淡出



目前,我的背景div文本会根据屏幕上的元素而变化。

有没有办法做到这一点:

  • 文本在用户滚动时淡出
  • 然后淡入,当div 位于屏幕中央时为 100%
  • 然后随着用户进一步滚动而淡出
  • 当用户向上滚动时执行相反的操作

我已经看到了基于JQuery的解决方案,但我想用vanilla javascript来完成这个。

const section = document.querySelectorAll('.check');
const bg = document.querySelector('.bg');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
className = entry.target.classList[1];
console.log(className);
if (entry.isIntersecting) {
if (className === 'first') {
bg.innerHTML = 'FIRST';
} else if (className === 'second') {
bg.innerHTML = 'SECOND';
} else if (className === 'third') {
bg.innerHTML = 'THIRD';
} else if (className === 'fourth') {
bg.innerHTML = 'FOURTH';
} else if (className === 'fifth') {
bg.innerHTML = 'FIFTH';
} else if (className === 'sixth') {
bg.innerHTML = 'SIXTH';
}
} else {
}
})
});
section.forEach(section => {
observer.observe(section);
});
.check {
width: 100px;
height: 20px;
background-color: red;
color: white;
padding: 20px;
}
.spacer {
height: 100vh;
width: 100px;
}
.bg {
position: fixed;
font-size: 100px;
color: #c9c9c9;
z-index: -100;
}
.fadeIn {
opacity: 1;
}
.fadeOut {
opacity: 0;
}
<div class="bg">
BG
</div>
<div class="check first">
FIRST
</div>
<div class="spacer">
</div>
<div class="check second">
SECOND
</div>
<div class="spacer">
</div>
<div class="check third">
THIRD
</div>
<div class="spacer">
</div>
<div class="check fourth">
FOURTH
</div>
<div class="spacer">
</div>
<div class="check fifth">
FIFTH
</div>
<div class="spacer">
</div>
<div class="check sixth">
SIXTH
</div>
<div class="spacer">
</div>

不是我最好的作品,而是那种作品

const section = document.querySelectorAll('.check');
const bgText = document.querySelector('.bg__text');
const capitalize = (value) => {
const [firstChar, ...rest] = value;
return firstChar.toUpperCase() + rest.join('').toLowerCase()
}
const checkpoints = Array.from(document.querySelectorAll(".check"))
.map(element => ({
id: element.classList[1],
element,
rect: element.getBoundingClientRect()
}));
let currentElement = null;
window.addEventListener("scroll", () => {
const scrollY = window.scrollY;
const innerHeight= window.innerHeight;

const distances = checkpoints.map(pr => ({
...pr,
distance: Math.abs(pr.rect.y - scrollY)
}));

distances.sort((prev, next) => prev.distance > next.distance ? 1 : -1);

const distance = distances.find(pr => pr.element === currentElement).distance;

let opacity = distance / innerHeight;
opacity = opacity > 0.5 ? 1 - opacity : opacity;
bgText.style.opacity = opacity * 2;

})
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
const element = entry.target;
className = element.classList[1];
if (!entry.isIntersecting) {
return;
}
currentElement = element;
bgText.textContent = capitalize(className);
})
});
section.forEach(section => {
observer.observe(section);
});
.check {
width: 100px;
height: 20px;
background-color: red;
color: white;
padding: 20px;
}
.spacer {
height: 100vh;
width: 100px;
}
.bg {
position: fixed;
font-size: 100px;
color: #c9c9c9;
z-index: -100;
}
.fadeIn {
opacity: 1;
}
.fadeOut {
opacity: 0;
}
<div class="bg">
<div class="bg__text"></div>
</div>
<div class="check first">
FIRST
</div>
<div class="spacer">
</div>
<div class="check second">
SECOND
</div>
<div class="spacer">
</div>
<div class="check third">
THIRD
</div>
<div class="spacer">
</div>
<div class="check fourth">
FOURTH
</div>
<div class="spacer">
</div>
<div class="check fifth">
FIFTH
</div>
<div class="spacer">
</div>
<div class="check sixth">
SIXTH
</div>
<div class="spacer">
</div>

最新更新