How to get offsetTop of element in regards to the document and not its parent?

Viewed 34

I had trouble wording my question, but here's the detail ! I've been struggling with how to get my navigation bullets (spans) to be highlighted when the current element is in viewport. I've initially tried using the same logic as a sidemenu tutorial I previously used elsewhere (by Web Cifar on youtube), but it doesn't quite work here. If I console(log) the .bullet-slider class, they correctly show up. What the problem is, from what I gather, is the offsetTop of my const bulletSlide can't be calculated because the parentElement is another div and not the document (is this right?). I've looked into using an Intersection Observer instead, but being new to javascript I'm struggling in how I could implement it into my existing structure.

Any help and/or tips would be greatly appreciated ! Thank you !

/**
* By Alvaro Trigo - horizontal scroll  
*/(function(){
    init();

    var g_containerInViewport;
    function init(){
        setStickyContainersSize();
        bindEvents();
    }

    function bindEvents(){
        window.addEventListener("wheel", wheelHandler);        
    }

    function setStickyContainersSize(){
        document.querySelectorAll('.sticky-container').forEach(function(container){
            const stikyContainerHeight = container.querySelector('.main').scrollWidth;
            container.setAttribute('style', 'height: ' + stikyContainerHeight + 'px');
        });
    }

    function isElementInViewport (el) {
        const rect = el.getBoundingClientRect();
        return rect.top <= 0 && rect.bottom > document.documentElement.clientHeight;
    }

    function wheelHandler(evt){
        
        const containerInViewPort = Array.from(document.querySelectorAll('.sticky-container')).filter(function(container){
            return isElementInViewport(container);
        })[0];

        if(!containerInViewPort){
            return;
        }

        var isPlaceHolderBelowTop = containerInViewPort.offsetTop < document.documentElement.scrollTop;
        var isPlaceHolderBelowBottom = containerInViewPort.offsetTop + containerInViewPort.offsetHeight > document.documentElement.scrollTop;
        let g_canScrollHorizontally = isPlaceHolderBelowTop && isPlaceHolderBelowBottom;

        if(g_canScrollHorizontally){
            containerInViewPort.querySelector('.main').scrollLeft += evt.deltaY;
        }
    }
})();

const bulletSlide = document.querySelectorAll('.bullet-slide');
const bulletGreen = document.querySelectorAll('.bullet-grn');
const bulletPink = document.querySelectorAll('.bullet-pink');

/*bullet highlight */ 
window.addEventListener('scroll', ()=> {
  let current = ''; 
  bulletSlide.forEach(bulletSlide => {
    const sectionTop = bulletSlide.offsetTop;
    const sectionHeight = bulletSlide.clientHeight;
    if (scrollY >= (sectionTop - sectionHeight / 3)) {
      current = bulletSlide.getAttribute('id');
    }
  ;
  })
  bulletGreen.forEach( span => {
    span.classList.remove('.bullet-grn-active');
    if(span.classList.contains(current)){
      span.classList.add('.bullet-grn-active');
    }
  })
  bulletPink.forEach( span => {
    span.classList.remove('.bullet-pink-active');
    if(span.classList.contains(current)){
      span.classList.add('.bullet-pink-active');
    }
  })
})
html {
    scroll-behavior: smooth;
} 
body {
    min-height: 100%;
    overflow-x: hidden;
}
.frame {
    min-height: 100vh;
    min-width: 100vw;
    padding-top: 20px;
}
.bg-grn {
    background: #CCD5AE;
}
.bg-lp {
    background: #E6C2CB;
}
.main {
    overflow-x: hidden;
    display: flex;
    position: sticky;
    top:0;
}
.main-slide {  
    min-width: 100vw;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
.wrapper {
    max-width: 600px;
    margin: 0 auto;
}
.col-2 { 
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    justify-content: space-between;
    align-items: center;
    gap: 80px;
}
.left-div {
    display: flex;
    flex-direction: column;
    gap: 20px;
    justify-content: center;
}
.col-1-3 {
    display: grid;
    grid-template-columns: 1fr 2fr;
    align-items: center;
    height: 100%;
    gap: 60px;
}
.bullets {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background-color: white;
    margin-right: 10px;
    cursor: pointer;
}
/* divider */
.divider {
    height: 40vh;
    width: 100vw;
    background-color: #FFD6C2;
    display: flex;
    align-items: center;
}
.div-wrapper {
    max-width: 600px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 20px;
}
<section>
    <div class="sticky-container frame bg-grn">
        <div class="main">
            <div id="etudes" class="main-slide bullet-slide"> 
                <div class="col-2 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="etudes bullets bullet-grn"></span>
                            <span class="micro bullets bullet-grn"></span>
                        </div>
                        <h2 class="title bk">Les études</h2>
                        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. At hic esse iusto excepturi. Rerum assumenda obcaecati voluptas velit, hic autem!</p>
                    </div>
                    <div>
                        <div id="dates-etudes">
                                <p><span class="date">2017</span>Master en Marketing et Vente</p> 
                                <p><span class="date">2015</span>Licence Langues Étrangères Appliquées</p>
                                <p><span class="date">2014</span>DUETI Business and Administration</p>
                                <p><span class="date">2013</span>DUT Techniques de Commercialisation</p>
                        </div>
                    </div>
                </div>
            </div>
            <div id="micro" class="main-slide bullet-slide">
                <div class="col-2 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="etudes bullets bullet-grn"></span>
                            <span class="micro bullets bullet-grn"></span>
                        </div>
                        <h2 class="title bk">La micro-entreprise</h2>
                        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos error hic totam provident delectus! Aliquid error debitis amet quos eaque?</p>
                    </div>
                    <div id="paper-container">
                        <p class="div-title">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Itaque, corporis! !</p>
                        
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>
<div class="divider">
    <div class="div-wrapper">
        <h3 class="div-title">Depuis janvier 2022</h3>
        <p class="div-p">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nisi ipsum eveniet voluptatem quis est nulla soluta ipsam voluptas fugiat odit..</p>
    </div>
</div>
<section>
    <div class="sticky-container frame bg-lp">
        <div class="main">
            <div id="pas1" class="main-slide bullet-slide">
                <div class="col-1-3 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="pas1 bullets bullet-pink"></span>
                            <span class="pas2 bullets bullet-pink"></span>
                            <span class="pas3 bullets bullet-pink"></span>
                            <span class="pas4 bullets bullet-pink"></span>
                        </div>
                        <h2 class="title">Mes premiers pas dans le web design</h2>
                    </div>
                    <div>
                        <div class="title-para">
                            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim numquam vero recusandae provident, sapiente tempora sequi modi laboriosam velit dolorum!</p>
                            <div class="bg-pink-ptn">
                                <h4>Les axes de réflexion</h4>
                                <div class="list col-2">
                                    <ul>
                                        <li>l'aspect graphique et esthétique</li>
                                        <li>l'objectif du site</li>
                                        <li>le contenu & son organisation</li>
                                    </ul>
                                    <ul>
                                        <li>les fonctionnalités</li>
                                        <li>l'évolution prévue</li>
                                        <li>la gestion du site</li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div id="pas2" class="main-slide bullet-slide">
                <div class="col-1-3 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="pas1 bullets bullet-pink"></span>
                            <span class="pas2 bullets bullet-pink"></span>
                            <span class="pas3 bullets bullet-pink"></span>
                            <span class="pas4 bullets bullet-pink"></span>
                        </div>
                        <h2 class="title">Mes premiers pas dans le web design</h2>
                    </div>
                    <div  class="title-para">
                        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati consequatur molestias ab maxime, dolor dolorum esse incidunt dolores nulla alias?</p>
                        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Atque ex perferendis molestias sequi et aliquid nam corrupti quis voluptatum enim.</span></p>
                    </div>
                </div>
            </div>
            <div id="pas3" class="main-slide bullet-slide">
                <div class="col-1-3 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="pas1 bullets bullet-pink"></span>
                            <span class="pas2 bullets bullet-pink"></span>
                            <span class="pas3 bullets bullet-pink"></span>
                            <span class="pas4 bullets bullet-pink"></span>
                        </div>
                        <h2 class="title">Mes premiers pas dans le web design</h2>
                    </div>
                    <div class="title-para">
                        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos, ratione? Iure deleniti mollitia ea provident labore alias quo minus placeat? Voluptates veritatis praesentium debitis officiis ducimus quae consectetur, qui laudantium modi eveniet aspernatur fugit, veniam rerum dolorum id temporibus provident!</p>
                    </div>
                </div>
            </div>
            <div id="pas4" class="main-slide bullet-slide">
                <div class="col-1-3 wrapper">
                    <div class="left-div">
                        <div class="slide-bullets">
                            <span class="pas1 bullets bullet-pink"></span>
                            <span class="pas2 bullets bullet-pink"></span>
                            <span class="pas3 bullets bullet-pink"></span>
                            <span class="pas4 bullets bullet-pink"></span>
                        </div>
                        <h2 class="title">Mes premiers pas dans le web design</h2>
                    </div>
                    <div class="title-para">
                        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam molestiae, minima quo voluptas deleniti aliquid blanditiis beatae! Officiis, eos commodi!</p>
                    </div>
                </div>
            </div>
        </div>
    </div> 

0 Answers
Related