Skip to content
Advertisement

Intersection Observer API Fires callback even element is not in view

I am trying to find when the element is on screen(trying to implement the infinite loader).

Bind the Observer for the last item in the list and listen, unfortunately in chrome 62 mac 10.10 , callback is firing even though the element which I am observing is not in the viewport.

I could prevent it easily when I checked the intersection ratio. is this the way Intersection Observer will work?

Thanks in advance for any help.

bindIO();


function ioCallback(entries, observer) {
    console.log("entries");
    console.log(entries);
    entries.forEach(entry => {
        // Each entry describes an intersection change for one observed
        // target element:
        console.log(entry.boundingClientRect);
        console.log(entry.intersectionRatio);
        console.log(entry.intersectionRect);
        console.log(entry.isIntersecting);
        console.log(entry.rootBounds);
        console.log(entry.target);
        console.log(entry.time);
    });
}

function bindIO(arguments) {
    var options = {
        threshold: 1.0
    }

    observer = new IntersectionObserver(ioCallback, options);
}
var triggerel;
var lastIndex;
var items;
var observer;

setTimeout(function() {
    observeEl();
}, 2000);


function observeEl(arguments) {
    items = document.querySelectorAll('.item');
    lastIndex = items.length
    triggerel = items[lastIndex - 1];
    observer.observe(triggerel);

}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/>
        <title>HTML BolierPlate</title>
        <link rel="stylesheet" type="text/css" href="css/reset.css"></link>
        <link rel="stylesheet" type="text/css"  href="css/mystyle.css"></link>
        <style>
            .item{

                background: green;
                margin: 30px;
                height: 400px;
                width: 400px;
                color: black;
                font-weight: black;
            }
            
        </style>

    </head>

    <body>
        
        Welcome to BoilerPlate!!!
        


        <div class="item-1 item">
            
            Items #1 

        </div>

        <div class="item-2 item">
            
            Items #2 

        </div>

        <div class="item-3 item">
            
            Items #3 

        </div>

        <div class="item-4 item">
            
            Items #4 

        </div>

        <div class="item-5 item">
            
            Items #5 

        </div>

        <div class="item-6 item">
            
            Items #6 

        </div>

        <div class="item-7 item">
            
            Items #7 

        </div>

        <div class="item-8 item">
            
            Items #8 

        </div>

        

        <script src="js/lib/jquery.min.js" ></script>
        <script src="js/myscript.js" ></script>
       
    </body>
</html>

Advertisement

Answer

Indeed you’ve touched something which seems counter-intuitive.

When the IntersectionObserver is instantiated the callback is run once as detection of whether the element is in view or not (and correctly reports the intersecting attribute as false if it’s not in view).

The simplest way to go about it is by checking against the .isIntersecting attribute before running any functionality that should only kick in when the element is actually visible.

let observer = new IntersectionObserver(function (entries){
        entries.forEach(function(each,index){
            if(each.isIntersecting){
                console.log(each,each.isIntersecting);
            }
        })
    });

in the above solution, your desired code will execute once if the isIntersecting attribute is true. and the isIntersecting attribute is true, only if the element is truly visible (according to the threshold definition in observer configuration) neither in instantiation nor in disappearing of the target.

Hope this helps confirm you were on the right path while checking for those things, you haven’t done any mistakes.

Advertisement