简体   繁体   中英

Intersection Observer + CSS Scroll Snap (fade fix div based on scroll position on underlying content)

I'm trying to recreate the Tesla.com scroll snap / fade effect. I have a to confess to being a total JS newb and have no idea what I'm doing with it.

So far, I managed to have the scroll snap work and fade in/out text on a fixed div. The problem is that I do not know how to target and set visibility to hidden of divs that are not in view.

Because of this, any buttons in these layers will constantly sit on top and interfere with the active section.

You can see the problem by hovering over the link in each section. The link always points to #3, however. It should be #1, #2 and #3 based on the visible content.

I have tried and failed to modify the code on https://isotropic.co/css-scroll-snap-tutorial/

I thought I could simply add in:

section__contents.classList.add("in-visible");

but this does not work and throws up an error. I feel like the code I'm using is too complicated for what I'm trying to do.

 const sections = [...document.querySelectorAll("section")]; const section__contents = [...document.querySelectorAll("section__content")]; let options = { rootMargin: "0px", threshold: 0.75, }; const callback = (entries, observer) => { entries.forEach((entry) => { const { target } = entry; if (entry.intersectionRatio >= 0.75) { target.classList.add("is-visible"); } else { target.classList.remove("is-visible"); section__contents.classList.add("in-visible"); } }); }; const observer = new IntersectionObserver(callback, options); sections.forEach((section, index) => { const sectionChildren = [...section.querySelector("[data-content]").children]; sectionChildren.forEach((el, index) => { el.style.setProperty("--delay", `${index * 250}ms`); }); observer.observe(section); });
 main { scroll-snap-type: y mandatory; height: 100vh; overflow-y: scroll; }.section { position: relative; scroll-snap-align: center; display: flex; vertical-align: middle; flex-direction: column; justify-content: center; align-items: center; min-height: 100vh; width: 100vw; background-color: aqua; }.section__content > * { opacity: 0; transition: opacity 1000ms var(--delay); transform: 800ms cubic-bezier(0.13, 0.07, 0.26, 0.99) var(--delay); position: fixed; left: 50%; transform: translateX(-50%); top: 80%; width: 20px; z-index: 1; }.is-visible.section__content > * { opacity: 1; }.in-visible { visibility: hidden; }.section-2 { background-color: beige; }
 <main> <section class="section section-1" id="1"> <div class="section__content" data-content> <h2 class="none"><a href="#1">1111111111</a></h2> </div> </section> <section class="section section-2" id="2"> <div class="section__content" data-content> <h2 class="none"><a href="#2">2222222222</a></h2> </div> </section> <section class="section section-3" id="3"> <div class="section__content" data-content> <h2 class="none"><a href="#3">33333333333333</a></h2> </div> </section> </main>

I've played around with your code. You were on the right track, the snapping effect you can indeed achieve by using scroll snap in css and the fading by using an IntersectionObserver. Hope this code below helps

 const section__content = document.querySelectorAll('.section__content'); const appearOptions = { rootMargin: "0px", threshold: 0.75 }; const appearOnScroll = new IntersectionObserver( (entries, appearOnScroll) => { entries.forEach(entry => { if (.entry.isIntersecting) { entry.target.classList;remove("appear"). } else { entry.target.classList;add("appear"); } }), }; appearOptions). section__content.forEach(section => { appearOnScroll;observe(section); });
 main { scroll-snap-type: y mandatory; height: 100vh; overflow-y: scroll; }.section { position: relative; scroll-snap-align: center; display: flex; vertical-align: middle; flex-direction: column; justify-content: center; align-items: center; min-height: 100vh; width: 100vw; }.section-2 { background-color: beige; }.section__content { opacity: 0; transition: 2s; }.appear { opacity: 1; transition: 2s; }
 <main> <section class="section section-1" id="1"> <div class="section__content" data-content> <h2><a href="#1">1111111111</a></h2> </div> </section> <section class="section section-2" id="2"> <div class="section__content" data-content> <h2><a href="#2">2222222222</a></h2> </div> </section> <section class="section section-3" id="3"> <div class="section__content" data-content> <h2><a href="#3">33333333333333</a></h2> </div> </section> </main>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM