如何使用 React 可见性传感器检测组件何时进入视口

介绍

程序式检测 React 组件进入 viewport时需要滚动事件倾听器并计算元素的大小。

使用 React 可见性传感器为您提供一个 React 组件,可为您完成此操作。

在本教程中,您将学习如何使用 React 可见度传感器来检测 React 组件进入 viewport 时。

前提条件

要完成本教程,您将需要:

本教程已通过 Node v15.3.0、npm v6.14.9、react v17.0.1 和react-visibility-sensor v5.1.1 进行验证。

步骤1 - 设置项目

考虑一个具有多个图像的页面的场景。当图像进入视图端口时,您希望应用CSS过渡,以便图像消失。

开始使用 create-react-app来生成 React App,然后安装依赖:

1npx create-react-app react-visibility-sensor-example

更改到新项目目录:

1cd react-visibility-sensor-example

安装反应可见性传感器包:

1npm install [email protected]

现在,您可以运行 React 应用程序:

1npm start

修复您的项目中的任何错误或问题,并在网页浏览器中访问localhost:3000

一旦你有一个工作 React 应用程序,你可以开始使用 viewport 检测来构建你的自定义组件。

步骤 2 – 应用 React 可见度传感器

使用您的文本编辑器创建一个新的VisibilitySensorImage.js文件:

 1[label src/VisibilitySensorImage.js]
 2import React, { Component } from 'react';
 3import VisibilitySensor from 'react-visibility-sensor';
 4
 5class VisibilitySensorImage extends Component {
 6  state = {
 7    visibility: false
 8  }
 9
10  render() {
11    return (
12      <VisibilitySensor
13        onChange={(isVisible) => {
14          this.setState({visibility: isVisible})
15        }}
16      >
17        <img
18          alt={this.props.alt}
19          src={this.props.src}
20          style={{
21            display: 'block',
22            maxWidth: '100%',
23            width: '100%',
24            height: 'auto',
25            opacity: this.state.visibility ? 1 : 0.25,
26            transition: 'opacity 500ms linear'
27          }}
28        />
29      </VisibilitySensor>
30    );
31  }
32}
33
34export default VisibilitySensorImage;

此组件使用由反应可见性传感器提供的可见性传感器组件。当检测到变化事件时,进行检查以确定该组件是否可见。

此代码使用三重运算符来确定是否将不透明度设置为0.251。如果图像不在视图端口,则适用于0.25的不透明度。

接下来,使用您创建的新组件来观察它在行动中。

打开App.js文件并修改它以使用VisibilitySensorImage:

 1[label src/App.js]
 2import VisibilitySensorImage from './VisibilitySensorImage';
 3
 4function App() {
 5  return (
 6    <div className="App">
 7      <h1>Astronomy</h1>
 8      {[
 9        'https://apod.nasa.gov/apod/image/2012/AntennaeGpotw1345a_1024.jpg',
10        'https://apod.nasa.gov/apod/image/2012/Neyerm63_l1_1024.jpg',
11        'https://apod.nasa.gov/apod/image/2012/2020Dec14TSE_Ribas_IMG_9291c1024.jpg',
12        'https://apod.nasa.gov/apod/image/2012/ChristmasTree-ConeNebula-CumeadaObservatoryDSA-net1100.jpg',
13        'https://apod.nasa.gov/apod/image/2012/EagleNebula_Paladini_960.jpg'
14      ].map((imgpath) => <VisibilitySensorImage src={imgpath} alt="Astronomy Image"/>)}
15    </div>
16  );
17}
18
19export default App;

现在,当您运行 React 应用程序时,您应该观察屏幕上出现的图像. 当您滚动到屏幕上时,图像的透明度应以消失的视觉效果改变。

然而,在本示例中,效果仅在狭窄的屏幕上可见。如果图像大于视图端口,则可能不会被检测为isVisible

步骤 3 – 定制 React 可见度传感器

React 可见度传感器的文档包含许多定制功能。

部分可见性支架将有助于解决比观看端口更大的组件的问题。

修改VisibilitySensorImage并添加部分Visibility:

 1[label src/VisibilitySensorImage.js]
 2import React, { Component } from 'react';
 3import VisibilitySensor from 'react-visibility-sensor';
 4
 5class VisibilitySensorImage extends Component {
 6  state = {
 7    visibility: false
 8  }
 9
10  render() {
11    return (
12      <VisibilitySensor
13        partialVisibility
14        onChange={(isVisible) => {
15          this.setState({visibility: isVisible})
16        }}
17      >
18        <img
19          alt={this.props.alt}
20          src={this.props.src}
21          style={{
22            display: 'block',
23            maxWidth: '100%',
24            width: '100%',
25            height: 'auto',
26            opacity: this.state.visibility ? 1 : 0.25,
27            transition: 'opacity 500ms linear'
28          }}
29        />
30      </VisibilitySensor>
31    );
32  }
33}
34
35export default VisibilitySensorImage;

现在,如果您滚动页面,当图像在视图端部分时,不透明度会发生变化。

除了部分可见性之外,还有许多自定义优惠:

  • 打破滚动听器
  • 指定视图端口中显示的最小像素数(默认情况:当部分可见性真实时,当只显示 1 个像素时,这些元素被认为是可见的)。

结论

在本教程中,您了解如何使用 React 可见度传感器来检测 React 组件进入 viewport 时。

本教程中的示例涉及图像在进入和离开观看端口时褪色,但还有其他用途的潜力:

  • 可在可见时放松地加载图像
  • 当用户滚到您的网站脚部时,显示谢谢访问!消息
  • 登录自定义事件到 Google Analytics
  • 当用户滚到博客帖子的末尾时,扩展评论小工具

如果您想了解更多关于 React 的信息,请查看我们的 如何在 React.js 中编码系列,或查看 我们的 React 主题页面以获取练习和编程项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus