Upon loading, the IntersectionObserver immediately declares the isIntersecting property true for all elements

Yesterday, when I executed this code, everything functioned as expected. The observer successfully loaded the images once they intersected the viewport:

<template>
  <div id="gallery" class="gallery">
    <div class="gallery-card">
      <a href="#"><img src="../../images/1.jpg"></a>
      <a href="#"><img src="../../images/ph.png" data-src="../../images/2.jpg"></a>
      <a href="#"><img src="../../images/ph.png" data-src="../../images/3.jpg"></a>
      <a href="#"><img src="../../images/ph.png" data-src="../../images/4.jpg"></a>
      <a href="#"><img src="../../images/ph.png" data-src="../../images/5.jpg"></a>
      <a href="#"><img src="../../images/ph.png" data-src="../../images/6.jpg"></a>
    </div>
  </div>
</template>


<script setup>
import {onMounted} from "vue";

onMounted(() => {
    let config = {
        rootMargin: '0px 0px 50px 0px',
        threshold: 0
    };

    const observer = new IntersectionObserver(function(entries, self) {
        console.log(entries)
        entries.forEach(entry => {
            if(entry.isIntersecting) {
                const img = entry.target
                img.src = img.dataset.src
                self.unobserve(img);
            }})
    }, config);

    const lazyImages = document.querySelectorAll('[data-src]');

    lazyImages.forEach(img => {
        console.log(img.src)
        observer.observe(img);
    });
})

</script>

However, today I noticed that the IntersectionObserver loads all the images at once upon initial page load. To troubleshoot this issue, I utilized console.log(), and strangely, the correct img element is being passed to the observer:

const lazyImages = document.querySelectorAll('[data-src]');
lazyImages.forEach(img => {
    console.log(img.src)
    observer.observe(img);
});

Output (x5, placeholder image):

http://localhost:3000/images/ph.png?3d03f427893c28791c9e0b8a347a277d

Nevertheless, the observer seems to be receiving an initial entries object with all isIntersecting properties set to true, leading to the loading of all images:

const observer = new IntersectionObserver(function (entries, self) {
    console.log(entries)
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target
            img.src = img.dataset.src
            self.unobserve(img);
        }
    })
}, config);

Output:

https://i.stack.imgur.com/5YUBcm.png

Is there a way to prevent this behavior?

Answer №1

Perhaps I'm a bit late to the party, but here are some ideas that might be useful.

 rootMargin: '0px 0px 50px 0px',
 threshold: 0

This translates to "use the viewport as the root and consider a 50px bottom margin below the viewport's bottom (refer to this image for a visual explanation of rootMargin)."

It's possible that all your images are already visible upon initial load, causing them to be intersected.

I encountered a similar issue with a custom implementation of scrollspy, dealing with the !isIntersecting condition. The problem was tackled by using a boolean flag that starts as false to capture the initial load, transitioning to true when scrolling begins.

In your scenario, switching the:

if (entry.isIntersecting) {

line to:

if (entry.isIntersecting && startedIntersecting) {

could potentially address the initial intersecting dilemma.

This code snippet captures the initial scroll, sets the flag to true, and ceases to capture further scroll events, leaving it to the IntersectionObserver to handle the rest.

To achieve this, I utilized RxJS's fromEvent in this manner:

startedIntersecting = false;

fromEvent(document, 'scroll').pipe(
  debounceTime(300),
  distinctUntilChanged(), 
  takeWhile(() => startedIntersecting !== true)
).subscribe($evt => {
  console.log('startedIntersecting', $evt);
  startedIntersecting = true;
});

I hope this sheds some light on the situation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Stop users from being able to copy text on their smartphones' internet browsers

I am currently working on creating a competitive typing speed challenge using JavaScript. Participants are required to type all the words they see from a div into a textarea. In order to prevent cheating, such as copying the words directly from the div, o ...

Leveraging the keyword 'this' within an object method in node's module.exports

My custom module: module.exports = { name: '', email: '', id: '', provider: '', logged_in: false, checkIfLoggedIn: function(req, res, next){ console.log(this); } }; I inclu ...

Manipulate SVG elements with JavaScript to embed a PNG image into the SVG file

Is it possible to edit an SVG, such as changing the fill color and other SVG methods? I am also looking to insert an SVG/PNG within another SVG at a specific path or group. Can someone provide guidance on how to achieve this? ...

The efficiency of XSL Template is significantly impacting loading time

Hello there, I am facing a challenge with my webpage's loading speed due to the code provided below. Can you assist me in optimizing it? <xsl:template match="Category" mode="CategorySelectorScript"> <xsl:variable name="ThisCateg ...

Unexpected errors causing havoc in my internet browser

I am facing difficulties uploading large files (~ 2 GB) on my server. To prevent crashes caused by huge files, I have removed the bodyParser from Express. However, the crash error occurs randomly, making it challenging to pinpoint the exact cause. The cod ...

What is the best way to execute AJAX requests in a loop synchronously while ensuring that each request is completed

I am looking to implement an AJAX loop where each call must finish before moving on to the next iteration. for (var i = 1; i < songs.length; i++) { getJson('get_song/' + i).done(function(e) { var song = JSON.parse(e); addSongToPlayl ...

The Javascript code I wrote is unable to detect the array element that was initially defined in Python

Trying to launch a new browser window through Selenium using driver.execute_script("window.open('');") However, the goal is to open a specific link provided by the user. For this purpose, extracted the link input from an array and inc ...

Ways to reduce the amount of time spent watching anime when it is not in view

My anime experiences glitches as the black container crosses the red, causing a decrease in duration. Is there a way to fix this glitch? I attempted to delay the changes until the red path is completed, but the glitches persist. delayInAnimeSub = ourVilla ...

Modifying the background color and linking it to a different class in Android Studio: A step-by-step guide

Recently, I developed a settings feature for my project that allows users to change the background color. However, I noticed that when I return to the home page, the settings are not saving or syncing properly. Any suggestions on how I can sync this info ...

Refresh div content dynamically with anchor tag in place

I have a dilemma with the following div that contains an anchor tag linking to a php script responsible for updating information in a database and returning to this page. My goal is to execute this php script by clicking on the anchor tag, update the datab ...

Tips to prevent encountering the "The response was not received before the message port closed" error while utilizing the await function in the listener

I'm currently in the process of developing a chrome extension using the node module "chrome-extension-async" and have encountered an issue with utilizing await within the background listener. In my setup, the content.js file sends a message to the ba ...

position: absolute is only applying to the initial item

I have a user card component with a menu button at the top that should display a menu when clicked. The issue I'm facing is that when I click on the menu button of the other user cards, the menu still shows on the first card instead of the one I click ...

Error in Node-Fetch Mapping: Unable to access property 'map' of an undefined entity

Encountering an issue with the "map" section when attempting to run it - receiving an error message stating "Cannot read property 'map' of undefined" The customers constant is defined above, so I'm unsure where the undefined value is origin ...

Utilizing a foundational element to automatically unsubscribe from multiple observable subscriptions

Within our Angular application, we have implemented a unique concept using a Base Component to manage observable subscriptions throughout the entire app. When a component subscribes to an observable, it must extend the Base Component. This approach ensures ...

Data object constructor is not triggered during JSON parsing

Currently, I am retrieving data from a server and then parsing it into TypeScript classes. To incorporate inheritance in my classes, each class must be capable of reporting its type. Let me explain the process: Starting with the base class import { PageE ...

How can I correctly parse nested JSON stored as a string within a property using JSON.parse()?

I am having trouble decoding the response from aws secretsmanager The data I received appears as follows: { "ARN": "arn:aws:secretsmanager:us-west-2:0000:secret:token-0000", "Name": "token", "VersionId&qu ...

The specified function 'isFakeTouchstartFromScreenReader' could not be located within the '@angular/cdk/a11y' library

I encountered the following errors unexpectedly while working on my Angular 11 project: Error: ./node_modules/@angular/material/fesm2015/core.js 1091:45-77 "export 'isFakeTouchstartFromScreenReader' was not found in '@angular/cdk/a11y&a ...

Creating dynamic styles with Material-UI's useStyles

Attempting to implement the same logic using material-ui's useStyle feature <div className={'container ' + (state.unlocked ? 'containerUnlocked' : '')}> I thought it might look like this: <div className={`${clas ...

Prevent Vue router back button from navigating to previous domains

I am facing a situation with my Vue 3 app that includes vue-router. In certain pages of the app, there is a back button available. When a user directly navigates to one of these back button pages such as /users/123sha256/ and clicks the back button, I have ...

What could be the reason for the sudden lack of content from the Blogger API?

For weeks, I've been using the Google API to retrieve JSON data from my Blogger account and showcase and style blog posts on my personal website. Everything was functioning flawlessly until yesterday when, out of the blue, the content section stopped ...