欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

react 滚动条组件_使用React和样式化组件的页面滚动进度条

程序员文章站 2022-03-30 15:57:28
...

react 滚动条组件

Let’s re-implement the progress bar on page scroll effect that you may have seen on many popular blogs including this one.

让我们重新实现页面滚动效果上的进度条,您可能已经在包括该博客在内的许多受欢迎的博客上看到了。

我们将如何做 (How we’ll do it)

To implement this, we would be making use of React, styled-components and the Document onScroll event. So, without further ado, let’s begin.

为了实现这一点,我们将使用React样式组件Document onScroll事件。 因此,事不宜迟,让我们开始吧。

安装 (Installation)

As stated, we’ll be using React and styled-components to implement the progress scroll effect. In order to save time, we’ll make use of Create React App to bootstrap a quick React application for us.

如前所述,我们将使用Reactstyled-components来实现进度滚动效果。 为了节省时间,我们将使用Create React App为我们引导一个快速的React应用程序。

So open your terminal and run the following commands:

因此,请打开您的终端并运行以下命令:

$ create-react-app app-name
$ cd app-name

Don’t have `create-react-app` installed? Then you can use this command $ npx create-react-app app-name

没有安装“ create-react-app”吗? 然后,您可以使用此命令$ npx create-react-app app-name

Alright so next up we need to also install styled-components to our newly created project. So while in the project directory, run

好了,接下来我们还需要将styled-components安装到我们新创建的项目中。 因此,在项目目录中运行

$ npm install styled-components -S

Now if you run npm start in our terminal, you should see something like this:

现在,如果您在我们的终端中运行npm start ,您应该会看到类似以下内容:

react 滚动条组件_使用React和样式化组件的页面滚动进度条



设计布局 (Designing the Layout)

So, now that our application is setup, let’s start writing some actual code. We’ll begin by building our page layout and writing some CSS to style the layout.

因此,既然我们的应用程序已经设置好,让我们开始编写一些实际的代码。 首先,我们将构建页面布局并编写一些CSS以对布局进行样式设置。

Navigate to your src/App.js file and then delete everything in the file and add the following lines of code:

导航到src/App.js文件,然后删除文件中的所有内容并添加以下代码行:

src/App.js
src / App.js
import React, { Component } from 'react';
import './App.css';

export default class App extends Component {
  render() {
    return (
      <div className="App">
        <header></header>
        <main>
          <h1>Lorem Ipsum</h1>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
          <p>...more paragraphs of text, enough so that the page gets a scrollbar</p>
        </main>
      </div>
    );
  }
}

Basically what we just did is convert the stateless functional component that create-react-app generated for us to a class-based component. We also added some dummy text content to fill up the page.

基本上,我们所做的就是将为我们生成的create-react-app的无状态功能组件转换为基于类的组件。 我们还添加了一些虚拟文本内容来填充页面。

Cool now to add some simple styling to the layout. Open the src/App.css and delete everything in it then add the following CSS lines to it.

现在很酷,为布局添加了一些简单的样式。 打开src/App.css并删除其中的所有内容,然后向其中添加以下CSS行。

header {
  background: linear-gradient(to right, #302E24, #28313E);
  height: 60px;
  width: 100%;
  box-shadow: 0 2px 20px 0 rgba(0, 0, 0, .1);
  margin-bottom: 70px;
}

.App p, .App h1 {
  margin: 30px auto;
  width: 800px;
}

Now running npm start , you should then see something similar to this:

现在运行npm start ,您应该会看到类似以下内容:

react 滚动条组件_使用React和样式化组件的页面滚动进度条



设计进度条 (Design the Progress Bar)

Okay so the next thing on our agenda would be to design the progress bar. To implement this, we will be making use of the styled-components library we installed.

好吧,我们议程上的下一件事就是设计进度条。 为了实现这一点,我们将使用已安装的styled-components库。

let’s create a file named Progress.js in our src folder. Once that is done, add the following lines of code to the file:

让我们在src文件夹中创建一个名为Progress.js的文件。 完成后,将以下代码行添加到文件中:

src/Progress.js
src / Progress.js
import styled from 'styled-components';

const  Progress  =  styled.div`
  position:  fixed;
  background:  linear-gradient(
    to right,
    rgba(250, 224, 66, .8) ${props => props.scroll},
    transparent  0);
  width:  100%;
  height:  4px;
  z-index:  3;
`;

export  default  Progress;

Now, let’s head back to our App.js file and make use of the newly created Progress component:

现在,让我们回到App.js文件,并使用新创建的Progress组件:

src/App.js
src / App.js
import React, { Component } from 'react';
import './App.css';
import Progress from './Progress';

export default class App extends Component {
  render() {
    return (
      <div className="App">
        <Progress scroll="70%" />
        {/* ... */}
      </div>
    );
  }
}

Alright!, I guess this is a good time to check how we’re doing so far. So let’s run npm start once again and check out our application. If all goes well, you should have something like this:

好吧,我想现在是检查我们目前情况的好时机。 因此,让我们再次运行npm start并签出我们的应用程序。 如果一切顺利,您应该有以下内容:

react 滚动条组件_使用React和样式化组件的页面滚动进度条



添加滚动逻辑 (Adding the Scroll Logic)

Here comes the fun part, where we implement the scroll logic. Before we start writing the actual code, lets outline the steps that are required to achieve this:

这里是有趣的部分,我们在其中实现了滚动逻辑。 在开始编写实际代码之前,让我们概述实现此代码所需的步骤:

  • Listen for the scroll event on the document object

    监听document对象上的滚动事件

  • Determine the user’s current scroll distance

    确定用户当前的滚动距离
  • Have a state variable that holds the current scroll percentage

    有一个保存当前滚动百分比的状态变量
  • Finally, update the progress scroll with the new state percentage

    最后,使用新的状态百分比更新进度滚动

Alright let’s convert the pseudocode to actual code

好吧,让我们将伪代码转换为实际代码



监听文档对象上的滚动事件 (Listen for the scroll event on the document object)

Okay so in our App.js file, lets create a method called listenToScrollEvent that will listen for scroll events on the DOM. This method would look a little like this:

好的,在我们的App.js文件中,让我们创建一个名为listenToScrollEvent的方法,该方法将侦听DOM上的滚动事件。 该方法看起来像这样:

src/App.js
src / App.js
listenToScrollEvent = () => {
  document.addEventListener("scroll", () => {
    requestAnimationFrame(() => {
      // Calculates the scroll distance
      this.calculateScrollDistance();
    });
  });
};

The method simply listens for any scroll event that takes place on the Document object and then invokes requestAnimationFrame, which notifies the browser that an animation is about to take place. The browser then calls the calculateScrollDistance method that was specified in the requestAnimationFrame.

该方法仅侦听在Document对象上发生的任何滚动事件,然后调用requestAnimationFrame ,该事件通知浏览器动画即将发生。 然后,浏览器将调用requestAnimationFrame中指定的calculateScrollDistance方法。

One final step we need to do is call this method whenever the App component has mounted. So we take advantage of one of React’s lifecycle methods, componentDidMount, to call the listenToScrollEvent method.

我们需要做的最后一步是在安装了App组件后调用此方法。 因此,我们利用React的生命周期方法之一componentDidMount来调用listenToScrollEvent方法。

src/App.js
src / App.js
componentDidMount()  {
  this.listenToScrollEvent();
}

Now let’s take care of defining the calculateScrollDistance method.

现在让我们来定义一下calculateScrollDistance方法。



确定用户当前的滚动距离 (Determine the users current scroll distance)

To calculate the user’s current scroll distance, we need to do a few things:

要计算用户当前的滚动距离,我们需要做一些事情:

  • We need to get how much the user has scrolled

    我们需要获取用户滚动了多少
  • We need to get the browser’s height

    我们需要获取浏览器的高度
  • We need to get the document’s height

    我们需要获取文件的高度

获取用户滚动了多少 (Getting how much the user has scrolled)

To calculate the current user’s scrolled distance, we can make use of the pageYOffset value available on the windows object.

要计算当前用户的滚动距离,我们可以利用windows对象上可用的pageYOffset值。

So let’s create a calculateScrollDistance method and add the following line to the method:

因此,让我们创建一个calculateScrollDistance方法并将以下行添加到该方法:

src/App.js
src / App.js
calculateScrollDistance = () => {
  const scrollTop = window.pageYOffset;
}

In case of older IE browsers, the following should also work document.body.scrollTop

对于较旧的IE浏览器,以下内容也应适用于document.body.scrollTop

获取浏览器的高度 (Getting the browser’s height)

Next we need to get the browser’s height and to do that, we can make use of the innerHeight value that can be accessed via the window object.

接下来,我们需要获取浏览器的高度并执行此操作,我们可以利用可通过window对象访问的innerHeight值。

The browser’s height simply refers to the height of the viewable browser (i.e Chrome or Firefox) area.

浏览器的高度仅指可见浏览器(即Chrome或Firefox)区域的高度。

So back into our calculateScrollDistance, let’s add the line that gets the browser window height.

回到我们的calculateScrollDistance ,让我们添加获取浏览器窗口高度的行。

src/App.js
src / App.js
calculateScrollDistance = () => {
  const scrollTop = window.pageYOffset;
  const windowHeight = window.innerHeight;
}

In case of older IE browsers, the following should also work document.body.clientHeight

对于较旧的IE浏览器,以下内容也应适用于document.body.clientHeight

获取文件高度 (Getting the document height)

Now getting the document’s height is tricky and the reason behind this is because various browsers have different ways in which they interpret or calculate the height of a document.

现在获取文档的高度非常棘手,其背后的原因是因为各种浏览器使用不同的方式来解释或计算文档的高度。

To bypass this, we need to check different properties that various browsers use to get the document height and make use of Math.max() to get the highest value.

要绕过这一点,我们需要检查各种浏览器用来获取文档高度的不同属性,并使用Math.max()来获取最高值。

So let’s implement this quickly by creating a method called getDocHeight and add the following lines of code:

因此,让我们通过创建一个名为getDocHeight的方法并添加以下代码行来快速实现此目的:

src/App.js
src / App.js
getDocHeight  =  ()  =>  {
  return Math.max(
    document.body.scrollHeight,  document.documentElement.scrollHeight,
    document.body.offsetHeight,  document.documentElement.offsetHeight,
    document.body.clientHeight,  document.documentElement.clientHeight
  );
}

Then we call the method in our calculateScrollDistance method like so:

然后,在我们的calculateScrollDistance方法中调用该方法,如下所示:

src/App.js
src / App.js
calculateScrollDistance = () => {
  const scrollTop = window.pageYOffset;
  const windowHeight = window.innerHeight;
  const docHeight = this.getDocHeight();
}


Now that we have all the values we require, we can calculate the percentage a user has scrolled by dividing the scrollTop from the total available scroll length of the document (docHeight - winHeight) and multiply the result by 100 to get the result in percentage.

现在我们有了所需的所有值,我们可以通过将scrollTop除以文档的总可用滚动长度(docHeight-winHeight)并将结果乘以100得到百分比来计算用户滚动的百分比。

So add the following lines into our code:

因此,将以下行添加到我们的代码中:

src/App.js
src / App.js
calculateScrollDistance = () => {
  const scrollTop = window.pageYOffset;
  const windowHeight = window.innerHeight;
  const docHeight = this.getDocHeight();

  const  totalDocScrollLength  =  docHeight  -  winHeight;
  const  scrollPostion  =  Math.floor(scrollTop  /  totalDocScrollLength  *  100)
}

Now that we have scroll position, we need to add a state variable which we can then update with the current scroll position of the user. To do that, we need to create a state object in your src/App.js file and add a scrollPosition and then set the inital state to 0.

现在我们有了滚动位置,我们需要添加一个state变量,然后可以使用用户的当前滚动位置对其进行更新。 为此,我们需要在src/App.js文件中创建一个状态对象,并添加scrollPosition ,然后将初始状态设置为0。

src/App.js
src / App.js
// ...
state = {
  scrollPosition: 0
}

Back into our calculateScrollDistance method, we then need to make use of the setState method given by React which will help update the state of our scrollPosition:

回到我们的calculateScrollDistance方法中,然后我们需要使用React给出的setState方法,这将有助于更新scrollPosition的状态:

src/App.js
src / App.js
calculateScrollDistance = () => {
  // ...
  this.setState({
    scrollPosition,
  });
}

So the final code will look something like this:-

因此,最终代码将如下所示:-

src/App.js
src / App.js
// ...

state = {
  scrollPosition: 0
}

calculateScrollDistance  =  ()  =>  {
  const  scrollTop  =  window.pageYOffset;
  const  winHeight  =  window.innerHeight;
  const  docHeight  =  this.getDocHeight();

  const  totalDocScrollLength = docHeight  -  winHeight;
  const  scrollPostion  =  Math.floor(scrollTop  /  totalDocScrollLength  *  100);

  this.setState({
    scrollPostion,
  });
}

// ...


用我们的scrollPosition状态更新进度条 (Update the progress bar with our scrollPosition state)

Finally the last thing to do is to simply pass our scrollPosition state to our Progress bar component.

最后,最后要做的就是将我们的scrollPosition状态简单地传递给Progress栏组件。

{/* ... */}
<Progress  scroll={ this.state.scrollPostion  +  '%' }  />

So the final complete code would look something like this:-

因此,最终的完整代码应如下所示:-

import React, { Component } from 'react';
import Progress from './Progress';
import './App.css';

export default class App extends Component {
  state = {
    scrollPostion: 0
  }

  listenToScrollEvent = () => {
    document.addEventListener("scroll", () => {
      requestAnimationFrame(() => {
        this.calculateScrollDistance();
      });
    });
  }

  calculateScrollDistance = () => {
    const scrollTop = window.pageYOffset; // how much the user has scrolled by
    const winHeight = window.innerHeight;
    const docHeight = this.getDocHeight();

    const totalDocScrollLength = docHeight - winHeight;
    const scrollPostion = Math.floor(scrollTop / totalDocScrollLength * 100)

    this.setState({
      scrollPostion,
    });
  }

  getDocHeight = () => {
    return Math.max(
      document.body.scrollHeight, document.documentElement.scrollHeight,
      document.body.offsetHeight, document.documentElement.offsetHeight,
      document.body.clientHeight, document.documentElement.clientHeight
    );
  }

  componentDidMount() {
    this.listenToScrollEvent();
  }

  render() {
    return (
      <div className="App">
        <Progress scroll={this.state.scrollPostion + '%'} />
        <header></header>
        <main>
          <h1>Lorem Ipsum</h1>
          <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
          </p>
          <p>
          ...
          </p>
        </main>
      </div>
    );
  }
}

And with all of this in place, you should now have a working progress bar on page scroll!

有了所有这些之后,您现在应该在页面滚动上有了一个工作进度条!



那就是所有的人 (That’s All Folks)

Whew! ???? There you have it folks, we successfully created the progress scroll effect. Hopefully you find it useful!

ew! folk伙计们,我们成功创建了进度滚动效果。 希望您发现它有用!

翻译自: https://www.digitalocean.com/community/tutorials/react-progress-bar-on-scroll

react 滚动条组件