I'm having an issue with my progress bar in ReactJS - it seems to move when I scroll the window instead of

My code includes a progress bar that works fine - it shows a movable progress bar when the window is scrolled. However, I want the progress bar to move when scrolling inside my div, not on the entire window. I am currently using jQuery for this functionality.

Is it acceptable to write a jQuery function in componentWillmount?

export default class NewPreview extends React.Component {
    constructor(props) {
        super(props);
        self = this;
        this.scrollPercent=''
        this.xmlType=''
        this.d=''
        this.c=''
        this.state = {
        }
    }

  
    componentWillMount() {
      $(window).scroll(function () {
        console.log("h")
            var s = $(window).scrollTop()
                  this.d = $(document).height()
                  this.c = $(window).height()
                this.scrollPercent = (s / (d-c)) * 100;
                  var position = scrollPercent;
          
             $("#progressbar").attr('value', position);
          
          });
        
    }


    render() {
        const panel_body = {
            borderLeft: "3px solid #00BCD4",
            height: "90px",
            backgroundColor:"lightyellow",
            borderRadius:"4px",
            margin:"6px"
        }
        const progress ={
            width:"40%",
              position:"fixed",
              top:"103px",
              backgroundColor:"red"
          }
        const panel_XML = {
            color: "#00BCD4",
            fontSize: "17px",
            position: "relative",
            left: "12px",
            top: "10px"
        }
        if(this.xmlType='slideshow'){
            return (
                <div id="progressBarID">
                    <progress style={progress} id="progressbar" value="0" max="100"></progress>
                    {this.state.newXML.map((data,item)=>
                        <div class="panel panel-default" style={panel_body}>
                            <p style={panel_XML}>{data.header}</p>
                            <p style={panel_XML}>{data.article}</p>
                        </div>
                    )}
                </div>
            )
        }
        else if(this.xmlType='timeline') {
            return(
                <div>heloo</div>
            )
        }
    }

}

What steps should I take to make my progress bar move based on scrolling within my div instead of the window scroll?

Answer №1

You were almost there, but it's important to update the percent in the state so that the component can re-render (also changed to componentDidMount):

componentDidMount() {
  window.addEventListener('scroll', this.onScrollHandler);
}

componentWillUnmount() {
  // remove scroll listener
  window.removeEventListener('scroll', this.onScrollHandler);
}

// extracting the scroll handler into a function is recommended
onScrollHandler = () => {
  const s = $(window).scrollTop();
  const d = $(document).height();
  const c = $(window).height();
  const scrollPercent = (s / (d - c)) * 100;
  this.setState({
    scrollPercent
  });
}

Then adjust the css width based on the state:

const progress = {
  width: `${this.state.scrollPercent}%`,
  ...

If you only need to add a scroll listener, you can eliminate the use of jquery. I have updated the code to remove jquery as it's unnecessary here.


Check out the demo:

class NewPreview extends React.Component {
    constructor(props) {
        super(props);
        this.scrollPercent = 0;
        this.xmlType='slideshow'
        this.d=''
        this.c=''
        this.state = {
          newXML: []
        }
    }

    componentDidMount() {
      window.addEventListener('scroll', this.onScrollHandler);
    }
    
    componentWillUnmount() {
      // remove scroll listener
      window.removeEventListener('scroll', this.onScrollHandler);
    }
    
    onScrollHandler = () => {
      const s = $(window).scrollTop();
      const d = $(document).height();
      const c = $(window).height();
      const scrollPercent = (s / (d - c)) * 100;
      this.setState({
        scrollPercent
      });
    }

    render() {
        const panel_body = {
            borderLeft: "3px solid #00BCD4",
            height: "90px",
            backgroundColor:"lightyellow",
            borderRadius:"4px",
            margin:"6px"
        }
        const progress = {
            width: `${this.state.scrollPercent}%`,
              position:"fixed",
              top:"103px",
              backgroundColor:"red",
              height: '20px'
          }
        const panel_XML = {
            color: "#00BCD4",
            fontSize: "17px",
            position: "relative",
            left: "12px",
            top: "10px"
        }
        if(this.xmlType='slideshow'){
            return (
                <div id="progressBarID">
                    Scroll down
                    <div style={progress} id="progressbar" value="0" max="100"></div>
                    {this.state.newXML.map((data,item)=>
                        <div class="panel panel-default" style={panel_body}>
                            <p style={panel_XML}>{data.header}</p>
                            <p style={panel_XML}>{data.article}</p>
                        </div>
                    )}
                </div>
            )
        }
        else if(this.xmlType='timeline') {
            return(
                <div>heloo</div>
            )
        }
    }

}

ReactDOM.render(
  <NewPreview />,
  document.getElementById('app')
);
#app {
  border: solid 1px #000;
  height: 800px;
  overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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="app" />

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

What is the best way to eliminate the [lang tag] from a URL in Next.js?

I am looking to eliminate either the /en or the /it from the URL without explicitly adding it. i18next seems to be doing it automatically, and I am unsure how to disable this behavior. I simply want it to happen in the background. https://i.stack.imgur.co ...

Here's a guide on how to package and send values in ReactJs bundles

I'm currently involved in a ReactJs project that does not rely on any API for data management. For bundling the React APP, we are using Webpack in the project. The challenge now is to make the React APP usable on any website by simply including the ...

Show labels for data on a circular graph using angular-chart.js

I recently created a pie chart using angular-chart.js and it's functioning smoothly. However, I'm facing an issue with displaying the data value on each section of the pie chart. My attempt to use Chart.PieceLabel.js by adding the code snippet b ...

Tips for resolving this unhandled error in React TypeScript

After creating a program in React TypeScript, I encountered an uncaught error. Despite running and debugging tests and conducting extensive research on Google, I have been unable to resolve this issue on my own. Therefore, I am reaching out for assistance ...

Exploration of jQuery Dropdown Menus

Encountering a problem with my dropdown menu. Check out the code here: http://jsfiddle.net/xY2p6/1/ It seems like a simple issue that I can't figure out, but as shown in the link, the functionality is not working properly. I need help linking the hid ...

Is it possible to utilize a JS script generated within the body or head of an HTML file directly within CSS code?

As a beginner in webpage development, I have a query regarding the technical aspect. Is it possible to utilize variables from a JavaScript function, which is placed either in the head or body of an HTML file, directly in CSS code to make modifications such ...

How can I restrict the navigation buttons in FullCalendar to only allow viewing the current month and the next one?

I recently downloaded the FullCalendar plugin from Is there a way to disable the previous button so that only the current month is visible? Also, how can I limit the next button so that only one upcoming month is shown? In my header, I included this code ...

A guide on incorporating a customized Google map into your website

Recently, I utilized the Google Map editing service from this site: https://developers.google.com/maps/documentation/javascript/styling This link provided me with two things: 1. A JSON code 2. The Google API link However, I am unsure about how to incorpo ...

Generating a backup of the database using the web application's graphical user interface

Does anyone know if it's possible to create a database dump or back up data directly from the browser interface? I'm looking for a way to back up my database within my web application. ...

Creating a simulated textarea with a scrollbar and dynamically refreshing the content

Due to limitations on markup content inside <p> tags, I have decided to create my own custom textbox. This textbox will function as a console where the battle progress is logged. Initially, I attempted using nested divs for each log, but encountered ...

Run a Javascript function two seconds after initiating

My goal is to implement a delay in JavaScript using either setInterval or setTimeout, but I am facing an issue where the primary element is getting removed. Code that works fine without Javascript delay: const selectAllWithAttributeAdStatus = document. ...

Is selecting attributes with JQuery valHooks possible?

When it comes to JQuery Valhooks, there seems to be a limitation in their applicability or a lack of proper documentation. In my experience, I utilized valhooks with a select2 element by assigning a type value: $("#mySelect").select2(); $("#mySelect").se ...

Tips for choosing and deselecting data using jQuery

Is there a way to toggle the selection of data in my code? Currently, when I click on the data it gets selected and a tick image appears. However, I want it so that when I click again on the same data, the tick will disappear. How can I achieve this func ...

The ajax call is not yielding a successful response, consistently redirecting to the error function

My attempt to retrieve JSON data from a servlet is resulting in an error block response for every call, even though the backend is providing the correct response. Here is my JavaScript code: $(document).ready(function() { $("#submit").on("click", fun ...

Cease the continuous reloading of the website during the

Hi there! I have come across a little script that runs when the user clicks on "submit": $(document).ready(function(){ $("form").submit(function(){ var username = $("#username-field").val(); if(username) { $.ajax({ url: &ap ...

I want to create a feature in Angular where a specific header becomes sticky based on the user's scroll position on the

When working with Angular, I am faced with the challenge of making a panel header sticky based on the user's scroll position on the page. I have identified two potential solutions for achieving this functionality. One involves using pure CSS with pos ...

Differences between JSX and creating instances of component classes

Could someone please clarify the distinction between the following two statements? let instance1 = new CustomComponent(); and let instance2 = <CustomComponent /> When checking in the Chrome debugger, I see the following: for instance1 CustomComp ...

Error message: Unable to find child element in Selenium WebDriver

I'm currently dealing with a registration page where I encountered an issue. During my testing phase, I attempted to register without inputting a first name. Upon clicking the register button, I expected to see a 'Required' notification la ...

How to interact with AngularJS drop-down menus using Selenium in Python?

I have been working on scraping a website to create an account. Here is the specific URL: Upon visiting the site, you need to click on "Dont have an account yet?" and then click "Agree" on the following page. Subsequently, there are security questions th ...

Import different css packages depending on the theme selected using next-themes

Currently, my website is implementing next-themes for toggling between dark and light mode, along with using highlightjs for code highlighting. I am looking to import a dark variant when the theme is set to dark and vice versa. Take a look at the code sn ...