简体   繁体   中英

Change image shown in fixed div when another div is in viewport

I have a fixed div containing an image that scrolls with the user from the top of the page. As new content divs enter the viewport I want the image to change.

I found a related piece of code that will change the image based on how far a user scrolls in pixels. This works, but only if the viewport is a specific size, else the image changes too early/late:

Example

I'm trying to modify this so that the change is instead based on when another div comes into view so that it works no matter the screen size (content div heights are set with relative units). I think this can be done if the other divs positions are saved to a variable and then used in place of the pixel values in the above code. However I can't seem to get this right, probably because I've not calculated the other div positions correctly.

 $("#display1").fadeIn(1000); $(window).scroll(function() { var pos = $(window).scrollTop(); var first = $("#first").offset(); var second = $("#second").offset(); if (pos < first) { hideAll("display1"); $("#display1").fadeIn(1000); } if (pos > first && pos < second) { hideAll("display2"); $("#display2").fadeIn(1000); } etc... }); function hideAll(exceptMe) { $(".displayImg").each(function(i) { if ($(this).attr("id") == exceptMe) return; $(this).fadeOut(); }); } 

You should try

getBoundingClientRect()

JS method, since It gets the position of the elements relative to the viewport. Check this answer: https://stackoverflow.com/a/7557433/4312515

Here is a quick proof of concept of changing a background image based on an element getting into view.

There are three divs. When the third div reaches the bottom of the viewport it will change the color of the background. When the third divs scroll out of the view again the background color is reset to its initial color.

Normally you should debounce the scroll event to prevent slowing down the UI. For this example I didn't debounce the event so you get a better sense of when the background is changed.

 const card3 = document.getElementById('card3'), background = document.getElementById('background'); let isCardVisible = false; function checkDivPosition() { const cardTopPosition = card3.getBoundingClientRect().top, viewportHeight = document.documentElement.clientHeight, isInView = cardTopPosition - viewportHeight < 0; if (isInView && !isCardVisible) { background.style.backgroundColor = 'rebeccapurple'; isCardVisible = true; } else if (!isInView && isCardVisible) { background.style.backgroundColor = 'orange'; isCardVisible = false; } } function onWindowScroll(event) { checkDivPosition(); } window.addEventListener('scroll', onWindowScroll); 
 body { margin: 0; } .background { height: 100vh; opacity: .2; position: fixed; transition: background-color .3s ease-out; width: 100vw; } .card { border: 1px solid; height: 100vh; width: 100vw; } .card + .card { margin-top: 5vh; } 
 <div id="background" class="background" style="background-color:orange"></div> <div class="card"> Card 1 </div> <div class="card"> Card 2 </div> <div id="card3" class="card"> Card 3. </div> 

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