elem.getBoundingClientRect() не работает на мобильном экране

Я разрабатываю веб-сайт с использованием gatsby.js, и он включает анимацию слайдов при прокрутке вниз. Я написал код, который отлично работал, пока не открыл инструменты разработчика и не попробовал его с помощью панели инструментов устройства. вот демонстрация воспроизведения, а также веб-страница, чтобы упростить задачу https://getboundingclientrect-is-broken.netlify.app

      
        <div class="0 space"></div>

        <p class="1 slideFR"></p>
        <div id="boy" class="2 slideFL"></div>

        <p class="3 slideFR"></p>
        <div class="4 slideFL"></div>

        <div class="flx space"></div>
      
            .slideFR {
                width: 100px;
                height: 100px;
                background-color: #957b26;
                position: relative;
                left: 450px;

                transform: translateX(1000px);
            }
            .slideFL {
                width: 100px;
                height: 100px;
                background-color: #26958f;
                position: relative;
                left: 300px;

                transform: translateX(-1000px);
            }
            .inSight {
                transition: all 0.5s;
                transform: translateX(0);
            }
            .space {
                width: 100px;
                height: 1500px;
                background-color: aquamarine;
            }
      let elemsFL = document.getElementsByClassName("slideFL");
        var leftiesLoaded = Array.from( { length: elemsFL.length }, (_, i) => false ); // creates array length of elemsFL full of <false>

        let elemsFR = document.getElementsByClassName("slideFR");
        var rightersLoaded = Array.from( { length: elemsFR.length }, (_, i) => false ); // creates array length of elemsFR full of <false>

        document.addEventListener("scroll", function (event) {
            let windowHeight = window.outerHeight;
            console.log( "%c/* ----------- scroll ---------- */", "color: purple; font-weight: bold" );

            checkIfInSight(elemsFL, leftiesLoaded, windowHeight);
            checkIfInSight(elemsFR, rightersLoaded, windowHeight);
        });
        /* -------------------------------- touchmove ------------------------------- */
        document.addEventListener("touchmove", function (event) {
            let windowHeight = window.outerHeight;
            console.log( "%c/* ---------- touchmove --------- */", "color: red; font-weight: bold" );
            checkIfInSight(elemsFL, leftiesLoaded, windowHeight);
            checkIfInSight(elemsFR, rightersLoaded, windowHeight);
        });

        function checkIfInSight(elemArray, boolArray, windowHeight) {
            for (let counter = 0; counter < elemArray.length; counter++) {
                const elem = elemArray[counter];
                let elemRect = elem.getBoundingClientRect();
                let elemPosTop = elemRect.top;
                let elemPosBottom = elemPosTop + elem.scrollHeight;

                if (elemPosTop <= windowHeight && elemPosBottom >= 0) {
                    if (!boolArray[counter]) {
                        console.log( "%c In Sight", "color: green", elem.classList[0] );
                        boolArray[counter] = true;
                        elem.classList.add("inSight");
                    } else {
                        console.log( "%c In Sight And Loaded", "color: yellow", elem.classList[0] );
                    }
                } else {
                    console.log( elem.classList[0], "\tOut Of Sight", elemPosTop, "<=", windowHeight, "&&", elemPosBottom, ">=0\t\t\t", elem.offsetTop );
                    boolArray[counter] = false;
                    elem.classList.remove("inSight");
                }
            }
        }

Изменить: поскольку я устраняю неполадки, я заменилelem.offsetTopсwindow.scrollYчто действительно заставило меня понять, что по какой-то причине он довольно долго не интерпретирует действие прокрутки как фактическую прокрутку. Я до сих пор не знаю, что я делаю неправильно или в чем проблема

1 ответ

благодаря комментарию EmielZuurbier я нашел решение IntersectionObserver API.Я даже создал более чистый и оптимизированный код.

HTML

      
        <div class="0 space"></div>

        <p class="1 slideFR toSlide"></p>
        <div id="boy" class="2 slideFL toSlide"></div>

        <p class="3 slideFR toSlide"></p>
        <div class="4 slideFL toSlide"></div>

        <div class=" space"></div>

JS

      const slideDivs = document.querySelectorAll(".toSlide");
        const options={
            root: null,
            rootMargin: "0px 2000px",
        };

        const observer= new IntersectionObserver(function(entries, observer){
            entries.forEach(entry =>{
                console.log(entry.target.classList[0],entry.isIntersecting, entry.intersectionRect);
                if (entry.isIntersecting ){
                    entry.target.classList.add("inSight");
                }else {
                    entry.target.classList.remove("inSight");
                }
            });
        },options);
        slideDivs.forEach(slideDiv => {
            observer.observe(slideDiv);
        });

CSS

      
            .slideFR {
                width: 100px;
                height: 100px;
                background-color: #957b26;
                position: relative;
                left: 200px;

                transform: translateX(1000px);
            }
            .slideFL {
                width: 100px;
                height: 100px;
                background-color: #26958f;
                position: relative;
                left: 150px;

                /* visibility: hidden; */
                transform: translateX(-1000px);
            }
            .inSight {
                transition: all 0.5s;
                transform: translateX(0);
            }
            .space {
                width: 100px;
                height: 1500px;
                background-color: aquamarine;
            }
Другие вопросы по тегам