0

I am trying to create scroll effect, where on left side image is changing based on scroll position and right side is changing content while scrolling.

I am getting error when trying to execute onscroll javascript function. I am not sure what am I doing wrong - I am trying to use it in React App - is it possible that React has different rules to call this function?

I created example in here:

https://codesandbox.io/s/scroll-effect-37ecc

3
  • 1
    well. your scrollingDiv is null because the getElementById("scrollContainer") returns nothing. Since your component is not mounted, you wont have the div on the DOM. Try to put your code in useEffect Commented Aug 28, 2021 at 16:55
  • That actually solved it @Panther, I put the whole JS code in useEffect hook. Commented Aug 28, 2021 at 17:01
  • use "getElementByClassName" instead if getElementById and give a unique class to that element. also, add you call in useEffect. and use onScroll instead of onscroll Commented Aug 28, 2021 at 17:02

2 Answers 2

1

I would use useRef for dom manipulation in React. That will be optimized.

import { useLayoutEffect, useState, useRef, useEffect } from "react";
import { render } from "react-dom";
import classnames from "classnames";
import "./index.css";

const App = () => {
  // const scrollingDiv = document.getElementById("scrollContainer");
  // const img1 = document.getElementById("img1");
  // const img2 = document.getElementById("img2");

  const scrollingDiv = useRef(null);
  const image1 = useRef(null);
  const image2 = useRef(null);

  useEffect(() => {
    scrollingDiv.current.onscroll = function () {
    if (scrollingDiv.scrollTop < 250) {
      image1.current.src = "https://placeimg.com/250/100/arch";
      image2.current.src = "https://placeimg.com/250/100/animals";
    }

    if (scrollingDiv.current.scrollTop > 500) {
      image1.current.src = "https://placeimg.com/250/100/nature";
      image2.current.src = "https://placeimg.com/250/100/people";
    }
    if (scrollingDiv.current.scrollTop > 1000) {
      image1.current.src = "https://placeimg.com/250/100/tech";
      image2.current.src = "https://placeimg.com/250/100/any";
    }
  };

  }, []);


  return (
    <>
      <div class="container">
        <div class="left">
          <img ref={image1} id="img1" src="https://placeimg.com/250/100/arch" />
          <img ref={image2} id="img2" src="https://placeimg.com/250/100/animals" />
        </div>
        <div class="middle" ref={scrollingDiv} id="scrollContainer">
          <div class="in-middle">
            <div class="in-in-middle" id="1"></div>
            <div class="in-in-middle" id="2"></div>
            <div class="in-in-middle" id="3"></div>
          </div>
        </div>
      </div>
    </>
  );
};

render(<App />, document.getElementById("root"));

Or you can put direct listeners on the element as well using onSroll prop.

Also, don't forget to clear all the listeners in useEffect cleaning function, that way, you won't have any memory leak issues.

Sign up to request clarification or add additional context in comments.

Comments

0

normally, you would use useRef() function from react to get direct access to DOM elements, you can then use them like this:

const scrollingDiv = useRef(null);
<div id="scrollingSomething" ref={scrollingDiv}>

then you can manipulate the element using scollingDiv reference to the element

https://codesandbox.io/s/scroll-effect-forked-3nkbb

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.