Search code examples
htmljquerycssscroll

Applying classes to matching children based on div ID scroll


I'm trying to create a script that will match div ids that scroll into view with the corresponding children in a gallery. I don't want to have to create individual scrollTop codes for each div id—so needing some kind of variable for the index of each div id? I've struggled to find anything close online.

This is the simple scrollTop code I am using as an example. When the "in-view" class is applied, the corresponding gallery items change their opacity.

<script>
$(function(){
    $(document).scroll(function(){
        if($(this).scrollTop() >= $("#item-1").offset().top - 250) {
            $(".sticky-gallery .image-item:nth-child(1)").addClass("in-view");
        } else {
            $(".sticky-gallery .image-item:nth-child(1)").removeClass("in-view");
        }
    });
});
</script>

I'm hoping there's a way to create something that can flexibly work for #item-1 with nth-child(1), #item-2 with nth-child(2), etc...

Thank you for any guidance.


Solution

  • I think you can do this very simply by pairing off an array of the div elements with an array of the gallery elements. See the code below for a basic example.

    This satisfies the requirements:

    • matching scrolling divs with gallery items
    • changing gallery item's styling when matching div in view
    • no ids required on divs, and indeed no ids equired on gallery items

    var sections;
    var galleryItems;
    function getViewScrollingElements() {
        sections = document.getElementsByClassName("section");
        galleryItems = document.getElementsByClassName("item");
        //  Do first check before a scroll could have occured
        checkInView();
    }
    
    function checkInView () {
        var boundingRect;
        for ( var i = 0; i < sections.length; i++ ) {
            //  Get the extremities of the div
            boundingRect = sections[i].getBoundingClientRect();
            //  Are the div's extremities in view
            if ( boundingRect.top < window.innerHeight && boundingRect.bottom >= 0 ) {
                galleryItems[i].style.opacity = "1";
            } else {
                galleryItems[i].style.opacity = "0.2";
            }
        }
    }
    /*  The gallery */
    
    .gallery {
        position: fixed;
        top: 2vh;
        background: none;
        border: 2px solid red;
    }
    
    .item {
        opacity: 0.2;
        display: inline-block;
        border: 2px solid black;
        padding: 2px;
        margin: 2px;
    }
    
    
    /* The scrolling items */
    
    .section {
        height: 40vh;
    }
    
    /* Make sections stand out.*/
    
    .scroll_container > div:nth-of-type(odd).section {
        background: pink;
    }
    
    .scroll_container > div:nth-of-type(even).section {
        background: wheat;
    }
    <body onLoad="getViewScrollingElements()" onScroll="checkInView()">
    
    <div class="gallery">
        <div class="item">
            <p>Item 1</p>
        </div>
        <div class="item">
            <p>Item 2</p>
        </div>
        <div class="item">
            <p>Item 3</p>
        </div>
        <div class="item">
            <p>Item 4</p>
        </div>
        <div class="item">
            <p>Item 5</p>
        </div>
        <div class="item">
            <p>Item 6</p>
        </div>
        <div class="item">
            <p>Item 7</p>
        </div>
        <div class="item">
            <p>Item 8</p>
        </div>
        <div class="item">
            <p>Item 9</p>
        </div>
        <div class="item">
            <p>Item 10</p>
        </div>
        <div class="item">
            <p>Item 11</p>
        </div>
        <div class="item">
            <p>Item 12</p>
        </div>
        <div class="item">
            <p>Item 13</p>
        </div>
        <div class="item">
            <p>Item 14</p>
        </div>
        <div class="item">
            <p>Item 15</p>
        </div>
        <div class="item">
            <p>Item 16</p>
        </div>
        <div class="item">
            <p>Item 17</p>
        </div>
        <div class="item">
            <p>Item 18</p>
        </div>
    </div>
    
    <div class="scroll_container">
        <div class="section">
            <p>Section 1</p>
        </div>
        <div class="section">
            <p>Section 2</p>
        </div>
        <div class="section">
            <p>Section 3</p>
        </div>
        <div class="section">
            <p>Section 4</p>
        </div>
        <div class="section">
            <p>Section 5</p>
        </div>
        <div class="section">
            <p>Section 6</p>
        </div>
        <div class="section">
            <p>Section 7</p>
        </div>
        <div class="section">
            <p>Section 8</p>
        </div>
        <div class="section">
            <p>Section 9</p>
        </div>
        <div class="section">
            <p>Section 10</p>
        </div>
        <div class="section">
            <p>Section 11</p>
        </div>
        <div class="section">
            <p>Section 12</p>
        </div>
        <div class="section">
            <p>Section 13</p>
        </div>
        <div class="section">
            <p>Section 14</p>
        </div>
        <div class="section">
            <p>Section 15</p>
        </div>
        <div class="section">
            <p>Section 16</p>
        </div>
        <div class="section">
            <p>Section 17</p>
        </div>
        <div class="section">
            <p>Section 18</p>
        </div>
    </div>
    
    </body>