简体   繁体   中英

Check if child element is 100% visible inside a parent div that has overflow hidden

Good day,

I have a dynamic carousel that I want to check if the first slide and the last slide is 100% visible for the user and then it needs to trigger a function, currently I'm using getBoundingClientRect() but it uses the viewport and not the parent div.the parent div is not full width but is 80% of the viewport

This is my code to check the first slide, and it works with viewport:

JavaScript:

    function isInViewport(el) {
    const rect = el.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)

    );
}

    const box = document.querySelector('.firstSlide');
    const message = document.querySelector('#inView');

    console.log(box);
    document.addEventListener('click', function () {
        const messageText = isInViewport(box) ?
            'Yess its in view' :
            'Yess its not in view';

        message.textContent = messageText;

    }, {
        passive: true
    });

HTML:

            <div class="carousel" style="grid-template-columns: repeat(5, 585px); overfow:hidden, width:80%; margin:auto">
                <div class="image-container"><img src="image/url" alt=""></div>
                <div class="image-container"><img src="image/url" alt=""></div>
                <div class="image-container"><img src="image/url" alt=""></div>
                <div class="image-container"><img src="image/url" alt=""></div>
                <div class="image-container firstSlide"><img src="image/url" alt=""></div>
            </div>
<p id="inView">Yess its in view</p>

Is there a way so that it check if the child element is 100% in view of the parent element and not the entire viewport?

There is two ways to solve this issue.

  1. If you want to use getBoundingClientRect you can get the bounding box for the parent element. Calculate where this box is in the viewport. Then instead of comparing where the slide is compared to the viewbox, compare it to the boundingbox of the parent.

  2. (Best practice) The new fancy way. Use the Intersection Observer API, that api can be used to check if elements are in the viewport but can also be used directly to see where a element is compared to a ancestry element. The new api is also running by the browser and will not block the main thread which is really good for performance.

Here is a link to the Intersection Observer Api: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

The following code can determine if one bounding client rectangle is completely inside another.

 const d1 = document.getElementById('d1'); const d2 = document.getElementById('d2'); const p1 = document.getElementById('p1'); const p2 = document.getElementById('p2'); const r1 = document.getElementById('r1'); const r2 = document.getElementById('r2'); function isPVisible(element, container) { const elRect = element.getBoundingClientRect(); const conRect = container.getBoundingClientRect(); let result = false; if(elRect.x >= conRect.x && elRect.y >= conRect.y && elRect.x + elRect.width <= conRect.x + conRect.width && elRect.y + elRect.height <= conRect.y + conRect.height) { result = true } return result; } console.log(isPVisible(p1, d1)); console.log(isPVisible(p2, d2));
 #d1 { width: 40px; height: 10px; overflow: hidden; border: 1px blue solid; } #p1 { width: 50px; height: 30px; border: 1px red solid; } #d2 { width: 90px; height: 50px; overflow: hidden; border: 1px blue solid; } #p2 { width: 50px; height: 30px; border: 1px red solid; }
 <div id="d1"> <p id="p1">hello</p> </div> <div id="d2"> <p id="p2">hello</p> </div> <p> <span id="r1"></span> <span id="r2"></span> </p>

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