Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

106
Views
Updating image source on scroll using pure javascript

I'm trying to make a component that updates its source image on scroll when it gets referenced in its div tag ' infoBG 'in my main component. The function seems to work but I guess the return statement is overriding the function and just returns the original image without updating. What's the right way to do this so the function updates the first returned image?


function Infoimg () {

  window.addEventListener("scroll", event => {
    var scrollValue = window.scrollY;
    var image = document.getElementById('infoBG');
    if (scrollValue>100){
      image.setAttribute = ('src','images/ccpLogo.svg');
    }else{
      image.setAttribute = ('src','images/Passport Stock Photo.svg');
    }
    console.log(image)
    console.log(scrollValue);
  });
  
 return( 

 <img src={'images/Passport Stock Photo.svg'} alt='Info-Background'/>

 )
  
}

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

It is generally a bad idea to manipulate the DOM directly in React. Instead, rely on hooks and states to update variables that will be interpolated into your template instead.

In this case, it makes sense to create a new state using the useState hook to allow reading and writing of your image URL, and then use the setter returned by useState to update the value.

Moreover, some handful tips:

  1. You should use useEffect() and add the event listener on render
  2. You should also return a function in useEffect() to ensure that your scroll event listener is properly removed to avoid potential memory leaks and allow for garbage collection
  3. You can simplify your if/else statement into a simple ternary statement
  4. You might want to manually invoke onScroll() for the first time, especially if the user may arrive at the page with a cached scroll position (i.e. user does not start from top of page)

With all these points in mind, here is an improved version of your code:

const [image, setImage] = useState('images/Passport Stock Photo.svg');

useEffect(() => {
  const onScroll = () => {
    setImage(window.scrollY > 100 ? 'images/ccpLogo.svg' : 'images/Passport Stock Photo.svg');
  };

  // Note: Listen to scroll event
  window.addEventListener('scroll', onScroll);

  // Optional: Handle scenario where user arrives at a pre-scrolled position (non-zero scrollY on load)
  onScroll();

  // Note: Clean up to avoid memory leaks
  return () => {
    window.removeEventListener('scroll', onScroll);
  };
}, []);

return (
  <img src={image} alt="Info-Background" />
);
about 4 years ago · Juan Pablo Isaza Report

0

You basically need to use useRef, which could be better for performance. Remember that useState will trigger a re-render. But in fact, you just need to update the source of your image. I would use something like this.

import { useCallback, useEffect, useRef } from "react";

import "./styles.css";

export default function App() {
  const imgRef = useRef();
  const middleRef = useRef();

  const onScroll = useCallback(() => {
    if (imgRef != null) {
      var scrollValue = window.scrollY;
      if (scrollValue > 100) {
        imgRef.current.src = "https://picsum.photos/id/237/200/300";
      } else {
        imgRef.current.src = "https://picsum.photos/seed/picsum/200/300";
      }

      console.log(scrollValue);
    }
  }, []);

  useEffect(() => {
    window.addEventListener("scroll", onScroll, true);
    return () => {
      window.removeEventListener("scroll", onScroll, true);
    };
  }, [onScroll]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>

      <div ref={middleRef} className="middle" />
      <img
        ref={imgRef}
        src={"https://picsum.photos/seed/picsum/200/300"}
        alt="Info-Background"
      />
    </div>
  );
}

Here is the link. You can check it working on codesandbox. https://codesandbox.io/s/ecstatic-https-hzi5n

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!