Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a simple animation when the element(s) ($(.box-fadeTop)) reaches 1/3 of the page from the bottom.
And it goes like that:

if (the element reaches the 1/3 of the page from the bottom when scrolling){
//Do something (CSS for displaying the content)
}

It works well, but the problem is when there's more than one element that has the same class name $(.box-fadeTop);.
once I reach the first element it runs the function for all.

How can I set the function depending on each one of the elements positions (if there's more than one)?

Please Open the example in full screen.

var fadeTop = $(".box-fadeTop");
var fadeTopReachBottom = (fadeTop.offset().top - (window.screen.height))+ window.screen.height / 3.33;

$(window).scroll(function () {
    var winScrollTop = $(window).scrollTop();
    
    if(winScrollTop >= fadeTopReachBottom){
        $('.box-fadeTop').css({
            transform: 'translate(0, 0)',
            transition: 'all 1s',
            opacity: '1'
        }, 500, 'ease');
    }

});
*, *:before, *:after {
    margin: 0;
    padding: 0;
    -webkit-box-sizing: border-box; 
    box-sizing: border-box;
}

body {
    min-height: 3000px;
}

.box-fadeTop {
    width: 200px;
    height: 200px;
    border-radius: 4px;
    box-shadow: 0 0 1px 1px #888;
    margin: 0 auto;
    opacity: 0;
    transform: translate(50px, -50px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="margin-bottom: 1000px;"></div>

<div class="box-fadeTop"></div>

<div style="margin-bottom: 1000px;"></div>

<div class="box-fadeTop"></div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
172 views
Welcome To Ask or Share your Answers For Others

1 Answer

It is targeting them all because $(".box-fadeTop") is an array of all the elements with that class, you only want to target the element that is at 33% from the bottom.

This is a case where JavaScript's IntersectionObserver is the perfect solution. IntersectionObserver watches elements for their position relative to the window (or whatever else you specify) and performs actions based on whether they are intersecting.

// Get an array of your "watched" elements
let boxes = document.querySelectorAll('.box-fadeTop');

// Set an observer to watch their position, and run some code if they are at 33% from the bottom of the viewport
let observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            adjustCss(entry.target)
            // Stop watching them if we don't want to repeat
            self.unobserve(entry.target);
        }
    });
}, { rootMargin: '0px 0px -33% 0px' });

// Tell each individual "box" to be watched
boxes.forEach(box => {
    observer.observe(box);
});

// Function to run on the item that is intersecting
function adjustCss (box) {
    jQuery(box).css({
        transform: 'translate(0, 0)',
        transition: 'all 1s',
        opacity: '1',
        background: 'red'
    }, 500, 'ease');
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...