Improve the parallax effect in your React component

Do you have any tips on smoothing out the scrolling animation for a React component with a simple parallax effect? I tried using requestAnimationFrame() in vanilla JS, but it doesn't seem to work well within the React component's rendering cycle.

Also, is there a way to prevent changing the state of the element once it's out of view?

Check out my code implementation below:

const Parallax = React.createClass({
  getInitialState: function () {
    return {
      top: 0,
      opacity: 1
    };
  },

  parallax: function(event) {
    const scrollTop = window.pageYOffset;
    const elementHeight = this.splash.clientHeight;

    this.setState({ top: scrollTop * .7 + 'px' });
    this.setState({ opacity: (elementHeight - scrollTop) / elementHeight });
  },

  componentDidMount: function() {
    window.addEventListener('scroll', this.parallax);
  },

  componentWillUnmount: function() {
    window.removeEventListener('scroll', this.parallax);
  },

  render: function() {
    const splashStyle = { 
      transform: 'translateY(' + this.state.top +')',
      opacity: this.state.opacity
    };

    return (
      <div className="splash" 
        ref={ domElement => { this.splash = domElement; }}>

        <div className="splash__wrapper " style={ splashStyle }>
            <p>LONG CONTENT</p>
        </div>

      </div>
    );
  }

});

ReactDOM.render(
  <Parallax />,
  document.getElementById('container')
);
.splash {
      position: relative;
      width: 100vw;
      max-width: 100%;
      height: 100vh;
      min-height: 500px;
      background: url(https://facebook.github.io/react/img/logo_og.png) no-repeat 10% 60%;
      -webkit-background-size: cover;
      -moz-background-size: cover;
      -o-background-size: cover;
      background-size: cover;
    }
    
    .splash__wrapper {
      position: absolute;
      color: #fff;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      transition: 0s transform;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

Update:

I managed to limit state changes only when the Splash component is visible at the top of the page. However, I still can't improve the scroll performance.

if (scrollTop < elementHeight) {
  this.setState({ top: scrollTop * .7 + 'px' });
  this.setState({ opacity: (elementHeight - scrollTop) / elementHeight });
}

Answer №1

When a user scrolls down the page, numerous scroll events are triggered. It is not ideal to respond to each individual scroll event, so they can be grouped together, for example, every 1000 milliseconds.

This process is known as throttling. The lodash library offers a convenient throttle method for this purpose, although there are other options available.

If you include the lodash library, your event listener code would resemble the following...

window.addEventListener('scroll', _.throttle(this.parallax, 1000));

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

Ways to resolve the array to string conversion issue in PHP

In my PHP project, I am dealing with a dynamic array and trying to store the array result in a variable. However, I encountered an error: array to string conversion while coding. <?php require_once('ag.php'); class H { var $Voltage; ...

Can you explain how the Facebook Like button code functions and how I can create a similar feature on my own platform?

I have a website with 250 different items, each containing its own Like button using the standard Facebook "Like" code: div class="fb-like" data-href="http://www.mywebpage.com/myproductpage" data-send="false" data-layout="button_count" data-width="80" dat ...

Styling elements using flexbox and various other divs

Looking to style a webpage with CSS to achieve this particular layout: https://i.sstatic.net/K3x0A.png The objective is to make the page responsive where the red and blue columns (left and right) have fixed widths. The center column should be collapsible ...

Tips for locating precise information within nested object formations using Javascript

Within my code, I have showcased two distinct types of response. Upon closer examination of the following code snippets, it becomes evident that the structure of the response from a service differs slightly between the two types. In the first type, there i ...

What is the reason for the presence of additional space below when using x-overflow:hidden?

When I place two spans inside each other and use overflow-x:hidden on the inner span, it results in extra space below the inner span. Why does this happen? <span style="" class="yavbc-color-tip"><span style="">Some text</span></span&g ...

Implement safe instructions through communication between the client and server

I am currently using Fancy WebSockets in Javascript for communication with my php server to support my multiplayer game. At the moment, I am simply sending raw sockets (json) as Sending: {"command": "login", "data": {"id" : "1575","md5" : "6bd8937a8789a3 ...

Issue with Navigation Scrolling Feature on Wordpress

I am in the process of implementing a 'scroll-nav' for my website. To achieve this, I decided to separate the Navigation into two sections and incorporate some jQuery: <nav class="main-nav clearfix"> <?php wp_nav_menu(array('th ...

Adjust the background to scroll to the bottom of the image first and then change it to be fixed

Here is the code I have written: body{ margin:0; padding:0; line-height: 1.5em; background-image: url(http://fehlbelichtet.stefanwensing.de/wp-content/uploads/sites/6/2016/04/alte-strasse-endlos.jpg); background-repeat:no-repeat; background-attachment: ...

Saving information in node.js

My latest project involves creating an address book app using HTML, CSS, and JavaScript. The company provided me with a zip file containing the necessary resources to implement the app using node.js. However, my knowledge of node.js is limited and I have ...

React Native: Issue with the data section in FlatList

I encountered an issue while using Flatlist to address a problem, but I ran into an error with the data property of my Flatlist. The error message is not very clear and I'm having trouble understanding it ( No overload matches this call. Overload 1 of ...

The Reactjs router appears to be failing to render any components

webpack.config.js module.exports = { entry: { app: __dirname + '/src/index.js' }, output: { path: __dirname + '/public', filename: 'bundle.js' }, mode: 'development', devS ...

Using Angular to Bind JSON Data

I'm currently in the process of evaluating different JS frameworks for a project and I find myself torn between Angular and Ember. As I continue to explore Angular, I have a specific question regarding data binding to an external json file stored on S ...

Responsive design involves ensuring that web elements such as divs are properly aligned

I am currently working on aligning 2 divs in a specific way that is responsive. I would like the right div to stack on top of the left div when the screen width reaches a certain point, as opposed to them both taking up 50% of the container's width. ...

Button for AngularJS delete request

I have developed a live polling application that allows users to create, view, and delete questions from the table pools stored in the RethinkDB database. The issue lies with the delete functionality. While sending a DELETE request using POSTMAN successfu ...

What is the best way to call an API within a loop using Node.js?

How can I efficiently make API calls based on page numbers in a loop? I am using the request() function for API calling, but when debugging my code, the response block is not reached and I do not get a response. Can someone please provide guidance on how ...

Generate a div element dynamically when an option is selected using AngularJS

I'm having trouble dynamically creating div elements based on the selected option value, but for some reason ng-repeat isn't working as expected. Can you help me figure out what I'm missing? Here's the HTML snippet I'm using - &l ...

Is there a way to prevent navbar links from wrapping when closed with CSS?

Upon closing my side navbar, I encountered an issue where the links warp to the size of the navbar. I am seeking a solution to keep the links (highlighted in pink in the image below) the same size without warping. Is there a CSS technique to achieve this? ...

Java servlet, Selenium, and JavaScript are a powerful combination of tools that can

I am facing a situation where I need Selenium webdriver to be executed on the client side. On a webpage, I have a form with a Submit button inside it. The action attribute of the form calls a servlet named "servletName". Inside the servlet, the followin ...

Within a <div> element, there is a <span> element with a border and a specific line height. The

Can anyone explain why the border of the span is positioned next to the top? When I remove the display property for the span, it seems to work fine. Thank you. div { height: 80px; border: 1px solid green; line-height: 80px } .inner-span { heigh ...

React is throwing an error because it cannot access the property 'length' of an undefined value

TypeError: Cannot read property 'length' of undefined When I try to run my React app, I keep getting this error message from the compiler. What steps should I take to resolve this issue? request = (start,end) => { if(this.state.teams.lengt ...