首页 >web前端 >css教程 >使用 Angular 实现几乎无限滚动

使用 Angular 实现几乎无限滚动

Patricia Arquette
Patricia Arquette原创
2025-01-07 20:15:41531浏览

无限滚动已经存在了一段时间了。 基本思想:当您滚动时,新内容会在底部加载,从而创建看似无穷无尽的滚动。 实现起来很简单,但如果没有仔细规划,性能就会受到影响。 经过几次内容重新获取后,您可能会拥有数百个 DOM 元素,其中许多元素是不可见的。 幸运的是,存在一些模式可以缓解这种情况,我们将使用 Angular 来探索一种模式。

Virtually Infinite Scrolling with Angular

这是我们想要避免的。

虚拟滚动

虚拟滚动在任何时候仅渲染大列表的子集——与无限滚动不同。 它非常适合一次性渲染所有内容效率低下的大型数据集。 仅渲染可见(和近乎可见)的项目;当用户滚动时,项目会动态交换。 这显着减少了 DOM 元素,从而提高了性能。

虚拟滚动通过创建与视口高度匹配的容器来工作。 只有可见项目(加上缓冲区)才会在此容器中以特定的滚动深度呈现,并通过 CSS 进行管理。 滚动更新容器,显示新项目并删除视图之外的项目,调整滚动深度。 将此与无限滚动相结合,创建一个几乎无限的列表,而不会造成性能损失。

下面的示例显示了包含数千个项目的列表,但一次最多渲染 8 个。 滚动会调整 CSS 滚动高度,产生列表更长的错觉。

Virtually Infinite Scrolling with Angular

现实世界的例子

让我们构建一个 Angular 应用程序,从 Reddit 的分页 API 获取媒体并将其显示在虚拟滚动列表中。 它将包括一个用于子 Reddit 选择的搜索栏和一个过滤器。 向下滚动可加载更多内容。 我们的关键要求:

  1. 由 RxJS Observables 和异步管道驱动。
  2. 在 subreddit 或过滤器更改时重置内容,但不会在附加新内容时重置内容。
  3. 将以前的内容存储在内存中,以便无缝向上/向下滚动,无需多余的 API 调用。

我们将使用 @angular/cdk 包(包含 Virtual Scroller 组件)。使用npm i @angular/cdk安装它。

虽然此示例使用 Angular,但类似的模式也适用于 React、Vue 或 vanilla JavaScript。 此处提供了说明基本原理的基本演示。

服务设置

首先,我们创建一个服务,使用 Angular 的 HttpClient 和 RxJS Observables 从 Reddit API 获取内容来管理 subreddit 名称和过滤器。 (为简洁起见,省略了一些代码;完整的实现在这里)。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

内容获取方法在数据请求期间跟踪特定属性。 page 属性被添加到查询字符串中,以确保在最后一项之后获取新内容。 我们还过滤掉 NSFW 内容和缺少帖子提示的项目。这可确保仅显示预期的内容。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

query$ observable(之前被省略)在获取内容之前合并不同的 observable 流。 scan 运算符结合了先前和当前的流结果,构建跨多个页面的大型数据数组。

这允许广泛滚动;只有 subreddit 名称或过滤器更改才会触发完整的重新获取。 nextPagequery$ 的属性,存储当前集合中的最后一个项目 ID,用于确定在接近虚拟滚动条底部时要获取的下一页。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

RxJS 的强大之处在于组合和操作数据流。这使我们能够在业务逻辑到达组件之前对其进行处理,从而使组件保持清洁和可重用。

组件设置

接下来,我们使用 Angular 的 CdkVirtualScrollViewport 设置组件来显示内容。 一个方法处理视口底部附近的滚动,通过 subRedditPage$ observable 获取下一页。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

模板使用异步管道订阅query$。 注意:随着内容高度可变,虚拟滚动条变得更加复杂;为了提高性能,建议使用一致的物品高度。

<code class="language-html">// ... (Omitted for brevity) ...</code>

当用户接近底部时,onScroll 方法会获取更多内容。它使用 nextPage ID(来自 query$)并发送到 subRedditPage$,触发下一个 API 调用并通过 query$ 更新列表。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

搜索栏和选项卡控件也集成在一起(下面的简化示例)。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>

结论

这会创建一个几乎无限的滚动条。 您可以在此处进行测试。 Reddit 的 API 有速率限制;你可能会在测试过程中碰到它们。 有关更多详细信息,包括其他功能,请参阅 GitHub 存储库此处

以上是使用 Angular 实现几乎无限滚动的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn