记录--Loading 用户体验 - 加载时避免闪烁

这篇具有很好参考价值的文章主要介绍了记录--Loading 用户体验 - 加载时避免闪烁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--Loading 用户体验 - 加载时避免闪烁

在切换详情页中有这么一个场景,点击上一条,会显示上一条的详情页,同理,点击下一条,会显示下一条的详情页。

记录--Loading 用户体验 - 加载时避免闪烁

伪代码如下所示:

我们定义了一个 switcher 模版, 用户点击上一条、下一条时调用 goToPreOrNext 方法。该页面通过 loadingDone 状态判断是否展示加载效果。

// html
<thy-loading [thyDone]="loadingDone"></thy-loading>
<ng-container *ngIf="loadingDone">
	<styx-pivot-detail>
		...
		<thy-arrow-switcher
			...
		  (thyPrevious)="goToPreOrNext($event)"
		  (thyNext)="goToPreOrNext($event)"
		></thy-arrow-switcher>
	...
	</styx-pivot-detail>
</ng-container>

在 goToPreOrNext 方法中,当调用该方法时,通过 goToPreOrNextResolve 接口返回下一条的详情 id,通过该 id 请求详情数据。

// 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {
	...
	this.goToPreOrNextResolve(event.index, topicId).subscribe(
		(id: string) => {
			this.getDetail(id);
		}
		...
	)
}

// 请求详情数据
getDetail(postId: string) {
	this.loadingDone = false;
	this.store
      .fetchPost(postId)
      .pipe(
          finalize(() => {
              this.loadingDone = true;
          })
      )
      .subscribe();
}

这看起来好像没有什么问题,应该一般都是这么干的,我们运行看看。

记录--Loading 用户体验 - 加载时避免闪烁

🌠 如何切换时候不闪?

与最上面的相比,有没有发现每次切换时,都会闪一下,用户体验很不好,有没有办法可以解决它?

这个问题就是 loadingDone 的状态切换导致的,我们把 loadingDone 干掉是不是就可以了?

如下代码所示:

// 请求详情数据
getDetail(postId: string) {
  // 注释掉这一行
	// this.loadingDone = false;
	this.store
      .fetchPost(postId)
      .pipe(
          finalize(() => {
              this.loadingDone = true;
          })
      )
      .subscribe();
}

记录--Loading 用户体验 - 加载时避免闪烁

好像方案可行?

但是把网络调成低速 3G 后,会发现,我们的加载效果没了,页面像卡住了一样,这当然不行。

记录--Loading 用户体验 - 加载时避免闪烁

有没有更好的方案?

⏰ setTimeout 方案

把先前 loadingDone 状态不放到 getDetail 方法中,而是单独拿出来紧跟 this.getDetail(id) 后面。

代码如下:

// 定义一个 timer
**private timer = null;**

// 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {
    ...
    this.goToPreOrNextResolve(event.index, topicId).subscribe(
        (id: string) => {
            this.getDetail(id);

              **this.timer = setTimeout(() => {
               this.loadingDone = false;
              }, 500);**

        }
        ...
    )
}

// 请求详情数据
getDetail(postId: string) {
  // 删除掉该行loadingDone 代码
	**// this.loadingDone = false;**
	this.store
      .fetchPost(postId)
      .pipe(
          finalize(() => {
              this.loadingDone = true;
	     // 记得清除
	     **clearTimeout(this.timer);**
          })
      )
      .subscribe();
}

这么做的含义就是,我们给到 loadingDone 500ms 的缓冲时间,如果 500ms 内返回数据了,则没有 loading 的效果,如果没有加载回来,在会显示加载中。

一般情况如下所示:

记录--Loading 用户体验 - 加载时避免闪烁

 低速网络下的效果:

记录--Loading 用户体验 - 加载时避免闪烁

这确实是一种方案,但是总感觉哪里怪怪的。

这里是个定时任务并且 500ms 后触发。试想一种结果,当我快速点击下一条并且在 300ms 获取到了数据并把 loadingDone 状态置为 true, 但 500ms时,loadingDone 状态置为 false,造成假死的情况,显然这不是我们想要的。

那这该如何解决?

💎 RxJS 大法

抛去使用 setTimeout 的方案,我们对 getDetail 代码改成如下的形式。

大致的思路是,将请求的 loading 状态与数据获取的状态分离,并定义了两个流 result$showLoadingIndicator$

result$ 流请求到数据之后,之后之后的一些操作, showLoadingIndicator$ 流则负责 loading 状态的推送。

来看看怎么一步一步实现的:

首先我们定义一个请求的流。

const fetchPost$ = () => this.store.fetchPost(postId);

然后分别定义了两个流 result$ 和 showLoadingIndicator$。这里的 share() 函数是因为会有两个订阅它的地方。

 const result$ = fetchPost$().pipe(share());

 const showLoadingIndicator$;

然后我们来处理 showLoadingIndicator$ 流。

我们期望在 500ms 内请求到的数据,则不应该展示 loading,否则,应该展示 loading 状态。

const showLoadingIndicator$ = timer(500).pipe(mapTo(true), takeUntil(result$))

如果在 500ms 后很快请求到了数据,为了避免闪屏,我们需要让 loading 至少显示 1s。然后使用 merge() 合并这两种结果。

const showLoadingIndicator$ = merge(
      timer(500).pipe(mapTo(true), takeUntil(result$)),
      combineLatest(result$, timer(1000)).pipe(mapTo(false))
  ).pipe(startWith(false), distinctUntilChanged());

最后订阅它们。

result$.subscribe(
      result => {
         // 请求到结果后的操作
      },
      error => {
         // TODO
      }
  );

  showLoadingIndicator$.subscribe(isLoading => {
      // 更新 loadingDone 状态
      this.loadingDone = !isLoading;
  });

完整的代码如下:

// 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {
	...
	this.goToPreOrNextResolve(event.index, topicId).subscribe(
		(id: string) => {
		  this.getDetail(id);
		}
		...
	)
}

// 请求详情数据
getDetail(postId: string) {

  const fetchPost$ = () => this.store.fetchPost(postId);

  const result$ = fetchPost$().pipe(share());

  const showLoadingIndicator$ = merge(
      timer(500).pipe(mapTo(true), takeUntil(result$)),
      combineLatest(result$, timer(1000)).pipe(mapTo(false))
  ).pipe(startWith(false), distinctUntilChanged());

  result$.subscribe(
      result => {
         // TODO
      },
      error => {
         // TODO
      }
  );

  showLoadingIndicator$.subscribe(isLoading => {
      this.loadingDone = !isLoading;
  });
}

如果想更细致知道如何实现的,参考下面这篇文档:

Loading indication with a delay and anti-flickering in RxJS

记录--Loading 用户体验 - 加载时避免闪烁

本文转载于:

https://juejin.cn/post/7176943529057321017

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--Loading 用户体验 - 加载时避免闪烁文章来源地址https://www.toymoban.com/news/detail-642837.html

到了这里,关于记录--Loading 用户体验 - 加载时避免闪烁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 为你的网站加上Loading等待加载效果吧 | Loading页面加载添加教程

    为你的网站加上Loading等待加载效果吧 | Loading页面加载添加教程 效果图 : 教程开始 新建一个loading样式css 将以下代码放进去 然后引用这个文件 code #Loadanimation{    background-color:#fff;    height:100%;    width:100%;    position:fixed;    z-index:1;    margin-top:0px;top:0px;     } #Loadanimation

    2024年02月09日
    浏览(107)
  • 【实战】 六、用户体验优化 - 加载中和错误状态处理(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月15日
    浏览(36)
  • 【实战】 六、用户体验优化 - 加载中和错误状态处理(上) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(八)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月12日
    浏览(36)
  • 【实战】 六、用户体验优化 - 加载中和错误状态处理(中) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(九)

    学习内容来源:React + React Hook + TS 最佳实践-慕课网 相对原教程,我在学习开始时(2023.03)采用的是当前最新版本: 项 版本 react react-dom ^18.2.0 react-router react-router-dom ^6.11.2 antd ^4.24.8 @commitlint/cli @commitlint/config-conventional ^17.4.4 eslint-config-prettier ^8.6.0 husky ^8.0.3 lint-staged ^13.1.2 p

    2024年02月13日
    浏览(43)
  • vue element-ui Loading加载事件的使用以及自定义Loading加载动画

     elemen-ui官方使用 loading加载事件属性解释 element-loading-text 在绑定了 v-loading 指令的元素上添加 element-loading-text 属性,其值会被渲染为加载文案,并显示在加载图标的下方 element-loading-spinner 和 element-loading-background 属性分别用来设定图标类名和背景色值。 作为小白,这次主要

    2024年02月11日
    浏览(44)
  • vue页面加载闪烁问题

    页面加载时,进入页面会闪烁显示变量名。 给关联的dom添加 v-cloak 增加css样式

    2024年02月11日
    浏览(43)
  • 关于vue首屏加载loading问题

    注意:网上搜索出来的都是教你在index.html里面div id=\\\"app\\\"div class=\\\"loading\\\"/div或者在app.vue Mounte生命周期函数控制app和loading的显示和隐藏,这里会有一个问题,就是js渲染页面需要时间,一样会出现几秒钟白屏。mounted(包裹使用nextTick)执行回调div app的内容依然没有开始渲染。 正

    2024年02月09日
    浏览(43)
  • elementui 自定义loading动画加载层

    elementui 自定义loading动画加载层。 main.js中添加 使用: element官网: Loading 还可以以服务的方式调用。引入 Loading 服务: import { Loading } from ‘element-ui’ 在需要调用时: Loading.service(options); 其中 options 参数为 Loading 的配置项,具体见下表。LoadingService 会返回一个 Loading 实例,可通

    2024年02月09日
    浏览(42)
  • Flutter:EasyLoading(loading加载、消息提示)

    官方虽然提供了内置的加载指示器和提示信息,但是功能比较简陋,这里推荐: flutter_easyloading CircularProgressIndicator 加粗样式 官方地址 https://pub-web.flutter-io.cn/packages/flutter_easyloading 安装 官方在线示例 https://nslogx.github.io/flutter_easyloading/#/ 初始化 首先需要在 MaterialApp/CupertinoAp

    2024年02月16日
    浏览(38)
  • ElementUI浅尝辄止23:Loading 加载

    Loading加载组件:加载数据时显示动效。 常见于加载数据量大的业务操作,附带动态效果。 在表格等容器中加载数据时显示。 可自定义加载文案、图标和背景色。 页面数据加载时显示。 Loading 还可以以服务的方式调用。引入 Loading 服务: 在需要调用时: 其中  options  参数

    2024年02月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包