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

Creating a client-server application in JavaScript with the npm-net module

In my possession is a straightforward piece of code titled echo_server.js. It serves as a server that simply echoes back any text received from the connected client. var net=require('net'); var server=net.createServer(function (socket) { socke ...

The image is not appearing in my small AngularJS application

I have developed a small application that converts Fahrenheit to Celsius and I am trying to display a relevant image based on the Fahrenheit temperature input. However, I am facing difficulties in getting the image to display correctly. Can someone please ...

Chip input component in React

I've recently upgraded to React 17 and encountered an issue with chip input fields like material-ui-chip-input not working properly. I've tried various npm packages, but none of them seem to be compatible with React version 17. Does anyone know ...

Incorporating HTML themes within ReactJS

While I am still relatively new to ReactJS, I am eager to expand my understanding of it with this question. I have a preexisting HTML/CSS theme that I would like to integrate into a React application. Is there a method to incorporate this theme seamlessly ...

The primary origin of TypeScript is derived from the compiled JavaScript and its corresponding source map

Being new to sourcemaps and typescript, I am faced with a project that has been compiled into a single javascript file from multiple typescript files. The files available to me are: lib.js (the compiled js code of the project) lib.js.map (the source map ...

Can React Native support styling using server-side data?

One of my React Native (RN) components is rendering data from an external server. The data is enclosed within RN components. For example: ... <View> <Text>{this.props.db.greeting}</Text> </View> The 'DB' object is si ...

Arrange records in ascending order by phone number when multiple are returned on the same date

Currently, I am working on an Angular application that is designed to keep track of tuxedo rentals. The main feature of the app is a table that displays information from an array stored in the controller. The initial task I completed was listing the items ...

configure various search parameters simultaneously during the rendering process

Incorporating a Tree component from mui v5, I am aiming to include searchParams for the selected and expanded nodes. This task is accomplished using the useSearchParams hook from React Router (v6). The issue arises when both the selected and expanded even ...

Troubles arise with loading Ajax due to spaces within the URL

I currently have two python files named gui.py and index.py. The file python.py contains a table with records from a MYSQL database. In gui.py, there is a reference to python.py along with a textfield and button for sending messages. Additionally, the g ...

The button click function is failing to trigger in Angular

Within my .html file, the following code is present: The button labeled Data Import is displayed.... <button mat-menu-item (click)="download()"> <mat-icon>cloud_download</mat-icon> <span>Data Imp ...

What is the best way to add all IDs to an array, except for the very first one

Is there a way to push all response IDs into the idList array, excluding the first ID? Currently, the code below pushes all IDs to the list. How can it be modified to exclude the first ID? const getAllId = async () => { let res = await axios({ m ...

Utilize the active tabpanel MUI component with Next.js router integration

Trying to implement active tab functionality using router pid This is how it's done: function dashboard({ tabId }) { const classes = useStyles(); const [value, setValue] = React.useState(""); useEffect(() => { con ...

Quick Tip: Enhancing your build with static assets and implementing cache busting techniques

I am facing an issue with my large static files that need to be hashed for HTTP caching in Vite. When I place them in the public directory, Vite only copies them without appending a hash to the filenames. However, if I put them in the assets directory, Vit ...

Using Strapi and Next.js to retrieve user information

After searching for similar questions with no luck, I'm reaching out for help. Building an authentication system using Strapi and Next.js, I'm faced with a task that seems simple but eludes me. The main question is: How can the client retrieve u ...

Could you share the most effective method for implementing a live search feature using javascript or jquery?

While attempting to create a live search for a dataset containing over 10,000 rows, I specified the DOM structure that is available. Despite my efforts to check each result after a single input during the live search process, my browser keeps hanging. Is t ...

CSS Flexibility in Action

Presently, my tab bar has a fixed look as shown here: https://codepen.io/cdemez/pen/WNrQpWp Including properties like width: 400px; etc... Upon inspecting the code, you'll notice that all the dimensions are static :-( Consequently, I am encountering ...

Is there a way to transform an HTML table from a horizontal layout to a vertical

I have reorganized the bus seating layout horizontally using a table. However, I now need to transform it vertically for mobile phones without disrupting my existing code. My attempt at using transform(rotate90deg) achieved the desired result, but the tab ...

The solution to enabling multiple inputs when multiple buttons are chosen

Below is a link to my jsfiddle application: http://jsfiddle.net/ybZvv/5/ Upon opening the jsfiddle, you will notice a top control panel with "Answer" buttons. Additionally, there are letter buttons, as well as "True" and "False" buttons. The functionali ...

Ways to programmatically append data to an object using JavaScript

My dilemma involves an object: var myObject={}; accompanied by a function that appends values to the object: function appendData(id, name){ //logic to validate id and name format, specify conditions for name being "John" and id being "I23423" my ...

Stuck with the Same Theme in the AppBar of material-UI?

Currently, I am attempting to modify the theme of a material-UI AppBar by utilizing states. Strangely enough, although the icons are changing, the theme itself is not. If you'd like to take a look at the code, you can find it here: https://codesandbo ...