产品经理:实现一个微信输入框

news2024/11/23 9:23:49

近期在开发AI对话产品的时候为了提升用户体验增强了对话输入框的相关能力,产品初期阶段对话框只是一个单行输入框,导致在文本内容很多的时候体验很不好,所以进行体验升级,类似还原了微信输入框的功能(只是其中的一点点哈🤏)。

初期认为这应该改动不大,就是把input换成textarea吧。但是实际开发过程发现并没有这么简单,本文仅作为开发过程的记录,因为是基于uniapp开发,相关实现代码都是基于uniapp

简单分析我们大概需要实现以下几个功能点:

  • 默认单行输入
  • 可多行输入,但有最大行数限制
  • 超过限制行术后内容在内部滚动
  • 支持回车发送内容
  • 支持常见组合键在输入框内换行输入
  • 多行输入时高度自适应 & 页面整体自适应

单行输入

默认单行输入比较简单直接使用input输入框即可,使用textarea的时候目前的实现方式是通过设置行内样式的高度控制,如我们的行内高度是36px,那么就设置其高度为36px。为什么要通过这种方式设置呢?因为要考虑后续多行输入超出最大行数的限制,需要通过高度来控制textarea的最大高度。

<textarea style="{ height: 36px }" />

多行输入

多行输入核心要注意的就是控制元素的高度,因为不能随着用户的输入一直增加高度,我们需要设置一个最大的行数限制,超出限制后就不再增加高度,内容可以继续输入,可以在输入框内上下滚动查看内容。

这里需要借助于uniapp内置在textarea@linechange事件,输入框行数变化时调用并回传高度和行数。如果不使用uniapp则需要对输入文字的长度及当前行高计算出对应的行数,这种情况还需要考虑单行文本没有满一行且换行的情况。

代码如下,在linechange事件中获取到最新的高度设置为textarea的高度,当超出最大的行数限制后则不处理。

linechange(event) {
    const { height, lineCount } = event.detail
    if (lineCount < maxLine) {
        this.textareaHeight = height
    }
}

这是正常的输入,还有一种情况是用户直接粘贴内容输入的场景,这种时候不会触发@linechange事件,需要手动处理,根据粘贴文本后的textarea的滚动高度进行计算出对应的行数,如超出限制行数则设置为最大高度,否则就设置为实际的行数所对应的高度。代码如下:

const paddingTop = parseInt(getComputedStyle(textarea).paddingTop);
const paddingBottom = parseInt(getComputedStyle(textarea).paddingBottom);
const textHeight = textarea.scrollHeight - paddingTop - paddingBottom;
const numberOfLines = Math.floor(textHeight / lineHeight);

if (numberOfLines > 1 && this.lineCount === 1) {
    const lineCount = numberOfLines < maxLine ? numberOfLines : maxLine
    this.textareaHeight = lineCount * lineHeight
}

键盘发送内容

正常我们使用电脑聊天时发送内容都是使用回车键发送内容,使用ctrlshiftalt等和回车键的组合键将输入框的文本进行换行处理。所以接下来要实现的就是对键盘事件的监听,基于事件进行发送内容和内容换行输入处理。

首先是事件的监听,uniapp不支持keydown的事件监听,所以这里使用了原生JS做监听处理,为了避免重复监听,对每次开始监听前先进行移除事件的监听,代码如下:

this.$refs.textarea.$el.removeEventListener('keydown', this.textareaKeydownHandle)
this.$refs.textarea.$el.addEventListener('keydown', this.textareaKeydownHandle)

然后是对textareaKeydownHandle方法的实现,这里需要注意的是组合键对内容换行的处理,需要获取到当前光标的位置,使用textarea.selectionStart可获取,基于光标位置增加一个换行\n的输入即可实现换行,核心代码如下:

const cursorPosition = textarea.selectionStart;
if(
    (e.keyCode == 13 && e.ctrlKey) ||
    (e.keyCode == 13 && e.metaKey) ||
    (e.keyCode == 13 && e.shiftKey) ||
    (e.keyCode == 13 && e.altKey)
){
    // 换行
    this.content = `${this.content.substring(0, cursorPosition)}\n${this.content.substring(cursorPosition)}`
}else if(e.keyCode == 13){
    // 发送
    this.onSend(); 
    e.preventDefault();
}

高度自适应

当多行输入内容时输入框所占据的高度增加,导致页面实际内容区域的高度减小,如果不进行动态处理会导致实际内容会被遮挡。如下图所示,红色区域就是需要动态处理的高度。

主要需要处理的场景就是输入内容行数变化的时候和用户粘贴文本的时候,这两种情况都会基于当前的可视行数计算输入框的高度,那么内容区域的高度就好计算了,使用整个窗口的高度减去输入框的高度和其他固定的高度如导航高度和底部安全距离高度即是真实内容的高度。

this.contentHeight = this.windowHeight - this.navBarHeight - this.fixedBottomHeight - this.textareaHeight;

最后

到此整个输入框的体验优化核心实现过程就结束了,增加了多行输入,组合键换行输入内容,键盘发送内容,整体内容高度自适应等。整体实现过程的细节功能点还是比较多,有实现过类似需求的同学欢迎留言交流~

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

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

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

相关文章

matlab保存图片

仅作为记录&#xff0c;大佬请跳过。 即可。 参考 感谢大佬博主文章&#xff1a;传送门

Java算法_ 检查对称树(LeetCode_Hot100)

题目描述&#xff1a;给你一个二叉树的根节点 &#xff0c; 检查它是否轴对称。root 获得更多&#xff1f;算法思路:代码文档&#xff0c;算法解析的私得。 运行效果 完整代码 /*** 2 * Author: LJJ* 3 * Date: 2023/8/17 8:47* 4*/ public class SymmetricTree {static class…

Journal of Cheminformatics投稿经验分享

期刊名: Journal of Cheminformatics期刊名缩写:J CHEMINFORMATICS期刊ISSN:1758-2946E-ISSN:1758-29462023年影响因子/JCR分区:8.6/Q1SCI分区: CHEMISTRY, MULTIDISCIPLINARY 化学综合3区COMPUTER SCIENCE, INFORMATION SYSTEMS 计算机:信息系统2区COMPUTER SCIENCE, I…

AgentBench:AI智能体的应用前景——生产端的应用

生产端的应用 相比于消费端,AI智能体作为生产力工具的潜力则更为巨大。在现实中,很多工作需要专业化的数据作为支撑,通用化大模型显然不能胜任,这就给专用型的AI智能体留下了空间。在实践中,人们已经用大模型训练了不少专用的AI智能体。比如,不久前北京大学团队发行了一…

linux内核异步内存回收的另一个思路:基于冷热文件的冷热区域精准的回收冷文件页page(内核ko方案)

本文介绍的针对pagecache的异步内存回收方案与现有的思路有很大不同&#xff1a;内存回收的单位是一个个文件&#xff0c;再把文件的pagecache分成一个个小单元(或者叫区域)。提前判断出文件那些区域是频繁访问的(热区域)&#xff0c;哪些区域很少访问(冷区域)。异步内存回收线…

移动通信系统的LMS自适应波束成形技术matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..................................................................... idxx0; while idxx&…

深入探索Java中的File类与IO操作:从路径到文件的一切

文章目录 1. File类的作用与构造方法2. File类常用方法&#xff1a;获取、判断和创建2.1 获取功能方法2.2 判断功能方法2.3 创建和删除功能方法2.4 目录的遍历方法 3. 递归&#xff1a;探索更深的层次代码示例&#xff1a;递归遍历文件夹 结论 &#x1f389;欢迎来到Java学习路…

AI极客日报0817 - 微软、亚马逊如何借助AI提升用户体验?

&#x1f440;AI 日报合集 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 曾经&#xff0c;很多企业对ChatGPT的开放性表示担忧。如今&#xff0c;这些顾虑即将成为过去——微软带来了一个答案&#xff0c;推出了名为Azure ChatGPT的私有开源版本。那么&#xff0c;这一新版…

nodejs+vue+elementui多媒体作品信息共享平台开发_s2uq7

武理多媒体信息共享平台主要有管理员和用户两个功能模块。以下将对这两个功能的作用进行详细的剖析。 管理员模块&#xff1a;管理员是系统中的核心用户&#xff0c;管理员登录后&#xff0c;可以对后台系统进行管理。主要功能有个人中心、用户管理、作品分类管理、作品信息管理…

数据分析工具都有哪些?

简单介绍一下&#xff0c;数据分析是指适当的统计分析方法对收集来的大量数据进行分析&#xff0c;将它们汇总和理解消化&#xff0c;以求最大化地开发数据的功能&#xff0c;发挥数据的作用。 那么数据分析有哪些工具呢&#xff0c;是不是都需要掌握&#xff1f;当然不是的&am…

嵌入式设备应用开发(程序、静态库、动态库、配置文件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 一个程序要想正确地在设备上运行起来,那么基本步骤就是,首先编写好程序代码,接着用交叉编译器编译出来,最后将这个程序拷贝到嵌入式设备上。然后,我们可以通过console控制台的…

【图像分类】基于卷积神经网络和主动学习的高光谱图像分类(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【使用 k 折叠交叉验证的卷积神经网络(CNN)】基于卷积神经网络的无特征EMG模式识别研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

4.Vue

1.什么是Vue Vue是一套前端框架&#xff0c;免除原生JavaScript中的DOM操作&#xff0c;简化书写。 基于**MVVM(Model-View-ViewModel)思想&#xff0c;实现数据双向绑定**&#xff0c;将编程的关注点放在数据上。 官网&#xff1a;https://v2.cn.vuejs.org/ 框架&#xff1…

Linux 5种网络IO模型

Linux IO模型 网络IO的本质是socket的读取&#xff0c;socket在linux系统被抽象为流&#xff0c;IO可以理解为对流的操作。刚才说了&#xff0c;对于一次IO访问&#xff08;以read举例&#xff09;&#xff0c;数据会先被拷贝到操作系统内核的缓冲区中&#xff0c;然后才会从操…

DDD 架构分层,MQ消息要放到那一层处理?

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 本文的宗旨在于通过简单干净实践的方式教会读者&#xff0c;使用 Docker 配置 RocketMQ 并在基于 DDD 分层结构的 SpringBoot 工…

Nginx反向代理技巧

跨域 作为一个前端开发者来说不可避免的问题就是跨域&#xff0c;那什么是跨域呢&#xff1f; 跨域&#xff1a;指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器对javascript施加的安全限制。浏览器的同源策略是指协议&#xff0c;域名…

三维模型OSGB格式轻量化纹理压缩关键技术分析

三维模型OSGB格式轻量化纹理压缩关键技术分析 在三维模型应用中&#xff0c;纹理是一个十分重要的因素&#xff0c;可以使得模型更加真实、精细。随着移动设备和网络传输速度的限制&#xff0c;纹理数据也需要进行轻量化处理&#xff0c;而OSGB格式纹理压缩是一种常见且有效的技…

Android Studio使用OkHttp网络通信出现okio问题

最近使用Android Studio做个App&#xff0c;一开始集成的httpclient&#xff0c;但是Android对其支持性不是很好了&#xff0c;所以换成了okhttp。 集成okhttp 1、我在本地仓库&#xff0c;拷贝出来&#xff0c;放到系统的libs目录下。 2、选定okhttp-4.1.0.jar&#xff0c;右…

电视机看板大屏适配问题——js基础积累

直接上效果图&#xff1a; 下面直接写代码&#xff1a; 1.html部分的代码 <body><div class"container"><!-- 数据展示区域 --><div class"box"><div class"top">top</div><div class"bottom&…