将chart放入panel中出现滚动条_聊天场景在web前端开发中的体验与优化

在日常工作中,如下图的聊天场景是不是很熟悉,没错就是我们再熟悉不过的 QQ 和微信,一个正常的聊天界面大致上是长这个样子的:

850e980e8c6bacf63d59803932449785.png

这种聊天窗口的消息流有两个明显的特点:

  • 最新的消息和滚动条初始位置需要在列表的最底部
  • 下拉加载历史消息要在当前消息列表顶部进行衔接

一般来说要实现这样的功能,对于前端开发来说都不是难事,只要两步就可以了:

  1. 在第一屏消息渲染完之后设置容器的 scrollTop 为一个极大值,这样就把最新消息和滚动条初始位置定位到了最底部;
  2. 当滚动到顶部时渲染第二屏数据,接着设置容器的 scrollTop 为衔接的位置(也就是第二屏的总高度),这样就实现了前后两屏消息的衔接。

这样的 demo 只需要随手撸二三十行代码就实现了:

3f341c0e39ce3efd6136a1277003fcac.gif

一开始渲染消息 1~20,滚到顶部后渲染第二屏消息 ABCDEFGHIJK,看上去前后两屏消息的衔接很平滑很流畅。目前开源社区中也有很多现成的用 React 和 Vue 开发的聊天组件或者示例,他们基本也是用上面提到的思路或者借助 iScroll 实现的。

用上面这种思路跑在 Web 中是没有任何问题的,但是在小程序中的表现却大失所望,看一下用同样的方式应用到小程序后的实际效果:

93c68ba32a7d9e0588ca79296e24d797.gif
d75f076c49fe95970f17cbc977fcc63f.gif

从第一段视频(左)可以看到从列表进入到聊天页面后设置滚动条位置到底部发生了明显的跳动,先看到停留在顶部然后瞬间再去到底部;

第二段视频(右)滚动到顶部加载后,下一屏消息与当前消息的衔接出现了一个明显的跳动,也是先看到在顶部然后才去到预期的位置。

为什么这个思路在 Web 端体验这么好,到了小程序上体验就如此糟糕呢?原因其实很简单,这是由于小程序底层通信逻辑和视图更新机制造成的:

d0da5afb43d75ca3408624dcf2bdcf10.png

由于小程序跨线程通信和异步更新的特点,内容的渲染和滚动位置的设置无法保证完成的先后顺序,所以必然会先看到上一个位置一闪而过的画面。

既然是底层的问题,那么这种聊天场景在小程序中难道就玩不了了吗?当然也有尝试过用 opacity 过渡和滚动动画去缓解这种跳动,但都无法从根本上解决这两个体验问题。

a2eb1744164d08b48caa82157f60571b.gif

当各种常规方案尝试都不尽满意的时候,那就换个思路:从本质上来说,聊天窗口的消息流实际上是一个 “反自然” 的列表,因为在计算机的 “自然界” 和人们习以为常的使用方式上,列表的初始位置都是在最顶部,想要浏览列表更多的内容需要向下滚动,而聊天场景的特点是完全反常规的!

再回到这两个体验问题:为什么需要手动设置最新消息和滚动条到最底部,为什么不让它一开始就在底部?为什么需要要在列表顶部追加数据,为什么不让它在底部追加数据?所以有没有可能颠倒常规,做一个 “反向渲染” 的滚动列表呢?答案是肯定的!

首先像常规的列表一样去渲染,不需要做任何处理,第一条最新消息和滚动条的初始位置是自然地在最上面:

e15e2db0cf5c8c11403bce6cd6272e6f.png

然后把整个列表区域的包裹容器用 CSS 旋转 180°,这样第一条最新消息和滚动条初始位置就在最下面下了:

ba0d0cb23623ee233564d8ee8145ea43.png

不过此时整个列表是倒置渲染的,最后再把每一条消息组件用同样的方式旋转 180° 使它们显示回正常的视角,这样就实现了一个 “反向渲染” 的列表:

e260325b2d466d45a8e64aaafa9ed674.png

虽然是 “反向渲染”,但视觉上和正常的一模一样。此时顶部就变成了底部,向上追加数据变成了向下追加数据。最后看一下聊天列表使用 “反向渲染” 之后的体验效果:

457ad293da0d8b59f0655eb2d1e9fcc1.gif
18eb872fca45d13f8dfc780e11fe0551.gif

可以看到,下拉加载消息与当前消息的衔接非常平滑没有任何的跳动,实际上这个时候历史消息是在底部渲染的,只不过反向渲染让它看上去是在顶部渲染的;此外,页面一进来最新消息和滚动条位置无需任何处理自然地停留在最底部,接近原生体验。

这种 “反向渲染” 的思路用最少的代码就解决了消息场景在小程序上这种几乎无解的问题,并且达到了最优的体验,而实际上核心代码只有两行 CSS:

transform: rotate(180deg);direction: rtl;

整个过程无需任何手动设置滚动位置和计算第二屏总高度(实际上都不用关心它们),同样这种思路用在 Web 上也是 OK 的。当然用了反向渲染也有一些牺牲,比如 iOS 双击顶部栏回到顶部这个特点就不能用了,但总体来说获得体验上的优化是更多的。

9d938b9a9515903dcf15eec59d0078d2.gif

此外,聊天场景中的消息流通常也有这样的布局:

d64206c7c85b31d64758b0f0b1ace893.png

如果视觉上需要将自己和别人的消息方向分别位列两边对齐,那么利用这种 “反向渲染” 的思路,实现起来也非常容易,只需要对消息组件应用不同的 CSS 样式即可:

2932d6ddd0470b919ffb6ec2f233052a.png

消息流的每一条消息都是一个单独的组件,此时不需要为了区分不同的视角而去新写一个组件,也不需要改变现有组件的结构布局。

f5a781e5c009fce08a4e784fb53114dc.gif

❤️ 最后

如果你觉得这篇文章对你有帮助,点个「关注/转发」,让更多的人也能看到你的分享!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个(伪)MaterialDesign风格的博客园皮肤

皮肤长什么样,不用我说,相信各位点进来的看官都能看得一清二楚。 有关其他细节呢,也欢迎各位在我博客里逛逛,帮忙挑挑刺,提提建议。 由于水平有限,暂没能用CSS处理博客园的代码高亮字体,实在是有…

git checkout 单个文件_IntelliJ IDEA下的使用 Git

作者| JKYO链接 | cnblogs.com/pejsidney/p/9199115.html1、Git 简介Git是目前流行的分布式版本管理系统。它拥有两套版本库,本地库和远程库,在不进行合并和删除之类的操作时这两套版本库互不影响。也因此其近乎所有的操作都是本地执行,所以在…

小甲鱼c语言课后作业_知识,就是力量——山财“学习小课堂”助你蓄力

编者按少年,你渴望 知识的力量 吗?我们有山财最全的学习秘籍,只待你的耐心翻阅与潜心修炼!接下来,就让我们一起查收学习干货~内容摘要本系列推送分为【悦览篇】【干货篇】【招募篇】三大模块。【悦览篇】编者会为大家推…

初步认识spring mvc

spring mvc 01Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发&…

sdk怎么用_PLC不支持OPC UA怎么办?别问了看完你就懂了

经常有人会烦恼这个问题:我的上位机软件什么功能都有,也支持OPC UA了,现在项目上准备用OPC UA的方式来获取我的PLC的数据,但是我的PLC却不支持OPC UA,怎么办呢?有的人碰到这个问题后就开始了“病急乱投医”…

js学习大法:用好firebug,走遍天下都不怕

用js有一段时间了,但是一直手感不好。平时用DW来写js代码,常抱怨js的编辑器的自动代码提示和调试功能用起来很不爽,自动代码提示十分有限,而且写错一个单词这样的错误都要运行整个网页之后才发现。今天闲来无聊,翻看了…

python杀死了excel_Python杀死了Excel|自动更新表格,告别繁琐

大家好,又到了Python办公自动化专题。 今天我们讲解的案例是如何使用Python自动更新Excel表格,简单来说就是每天都会对Excel中多个sheet进行更新,需要操作完后可以用程序完成第一张sheet 汇总表的更新,大概就是这样👇当…

TP-LINK路由器连接网线上网教程(租房必备)

租的房子,房子里只有一根普通网线,连着房东家的路由器,这时可以使用TP-LINK路由器使用LAN-WAN级联的方式,在室内搭建一个局域网。 设置教程 准备材料:1根网线 重置路由器:启动路由器,使用牙签…

推荐一款非常强大的扒站工具

在平时的开发或者学习的过程中,我们难免会看到一些让人心动的网站,于是自己想把它弄下来,自己手工一个文件一个文件把它保存下来不太可能,那得累死你,下面我推荐一款扒站的神器,可以把你所喜欢的目标网站整…

无刷新分页 jquery.pagination.js

序言 这一款js分页使用起来很爽,自己经常用,做项目时总是要翻以前的项目看,不方便,这里就把他写出来方便自己以后粘帖,也希望能分享给大家。友情提示下:我有一片博客是用着个js实现的无刷新分页也很好用&am…

windows 10打开或禁用管理员账户

windows 10下默认关闭了管理员账户,因为权限太高,而且win 10推荐通过网络账户登录。如果要使用,可以通过下面的方式打开。 1、登录一个普通账户。 如果你是刚升级上来,普通账户都没有。那么,用别人的电脑下载安装老毛…

hbase filter原理_HBase应用|HBase在移动广告监测产品中的应用

1HBase在Ad Tracking的应用1.1Ad Tracking的业务场景Ad Tracking是TalkingData的移动广告监测产品,其核心业务模型是归因。App用户点击广告之后,及随后安装广告跳转到的应用或者游戏,Ad Tracking会对这些点击事件(用户点击广告的行为)和激活事…

eclipse 快捷键及插件

webstorm设置keymap为eclipse也可使用。 快捷键 快捷键用途使用方法编辑器事件ctrlt打开继承树将鼠标移到某个类上,按ctrltctrl/注释本行altshiefj生成属性注释,这杨的/**/ctrlalt 下箭头复制本行到下一行alt 下箭头移动本行到下一行ctrld删除整行alt/…

drools动态配置规则_关于规则引擎

很早之前就知道Drools,这几天正好有个项目,里面用了大量的规则定义,就想是否能采用Drools来解决。在github上分析了规则引擎项目,包括:Easy-ruleshttps://github.com/j-easy/easy-rules通过程序代码来完成规则引擎&…

linux安装mysql5.6

目录 准备工作 运行环境 确认你的安装版本 下载MySQL 安装MySQL 准备安装环境 编译和安装 配置MySQL 单实例配置 单实例配置方法 添加防火墙 启动MySQL 重启MySQL 多实例配置 什么是多实例 多实例配置方法 创建启动文件 初始化数据库 配置防火墙 启动MySQL 登陆MySQL 重启MySQL…

Spring 4 MVC入门实例

Spring 4发布很长一段时间了,从 Spring 3 到 Spring 4 有巨大的改变。网上还有很多教程是基于 Spring 3.0 的,甚至 Spring 2.5,要想按照网上的教程“按图索骥”还是挺困难的。纵有一些 Spring 4.0 MVC 的教程例子,也往往是 “Spri…

python写入二进制文件的库_python之写入二进制文件

概述 计算机都是以二进制存储文件的,如mp3、图片等,文本文件也是如此,在本节中以二进制模式写入文件 写文件的很多操作,与读文件的操作是相同的,建议先看 读取二进制文件 打开文件 读写文件,要先通过内置op…

gulp插件gulp-ruby-sass和livereload插件

gulp-ruby-sass是gulp的一个插件,主要是用来实现sass编译,livereload插件主要是实现文件保存时浏览器自动刷新,避免了手动f5的频繁的操作 准备工作:chrome浏览器安装livereload插件,没有安装的可以百度搜索或者FQ下载&…

eclipse 创建 maven web 项目教程

(1)新建一个Maven 项目 file –> new –> maven project 直接点 next 直接点 next 填写groupid和artifactid,这两个可以随便填,名称而已。填完 finish (2)将项目转成 Dynamic Web项目 选中项目&#…

sql backup database备份d盘_ClickHouse 备份与恢复

本文转载自 万能修实验室 作者:公先生 ID: dropudatabase我们评估一款数据库产品,除了稳定性和易用性外,数据安全也十分重要,备份与恢复往往是最后一道安全门。但如果备份策略不完善、恢复手段无效,一旦发生数据误删除…