2019/8/6


问题描述


简单描述

今天做了一个需求,就是使用textarea进行文本输入时,需要去后台请求字典项来自动完成一些预留的统一本文。刚开始感觉还蛮容易的,但是做到后面坑越来越大,因此记录一下详细的过程。(一个菜鸡后端程序猿,被逼着写前端,巨难受)

需要注意的点
  1. 由于业务需要,前端的textarea对应的数据是一个数组,即textarea有多项。【如果是只有一个对象的话会很容易】
  2. 前端监听字段变化有很多种办法,比如使用watch监听数组变化、computer计算属性、监听键盘事件,甚至使用jquery来监听焦点及文本变化等等。
  3. 需要自动完成提示框能够根据当前文本所在位置来进行显示,类似于QQ的@功能及各种输入法的功能。
  4. 可以考虑使用键盘上下键来进行选择,按回车键选择自动回复的内容,这样可以很大程度的方便用户。
成品展示

参考文献

如何实现textarea中输入@在当前文本的右下方出现一个div,里面选择人名

问题构思


  • 为textarea设置文本变化监听事件,并获取到当前textarea的数组下标。
  • 在数据库中新增自动回复的数据,使用like 'xxx%'进行匹配。(业务需求,只考虑开头匹配,中间文本不支持)。
  • 根据输入的文本,向后台请求自动完成字段。(由于有多个,因此返回值为一个List数组)
  • 将请求到的数组,使用v-for渲染在需要展示的ul组件上。
  • 获取当前textarea中光标所在的位置,便于对齐ul组件
  • 根据选中的li,将textarea对应数组的内容替换成当前选中li的文本。
    扩展选项
  • 监听键盘上下键,使得按上下键可以上下选择自动回复的文本。
  • 监听键盘回车键,按下回车也可以达到和点击li一样的效果。

【粗体标注的是本文的重点内容,删除线不在本文的介绍范围内】

解决方案及步骤


监听textarea文本变化

由于业务需要,要获取到当前输入的文本值, textarea对应的数组下标以及触发当前文本变化的DOM。 因此,watch和computer方法不太适用(也可能是我没使用好,但他们两都获取不到数组下标以及DOM)。最终我采用了监听键盘事件的方法。尽管功能实现了,但仍旧感觉有所欠缺。。。
使用vue监听textarea键盘事件代码如下:

<textarea style="margin-top: 10px" class="layui-textarea" v-for="(it, dex) in newApprove" :value="it"
v-model="newApprove[dex]" @keyup="autoCompletion(it, dex, $event)"></textarea>

其中newApprove为一个字符串数组:newApprove: [""],
autoCompletion用于监听文本的变化。方法第一个参数为当前文本、第二个为数组下标,第三个为事件。

atuoCompletion方法如下:

autoCompletion: function (text, index, e) {// 监听上键与下键,拦截默认事件并阻止冒泡if(e.keyCode === 38 || e.keyCode === 40) { e.stopPropagation();e.preventDefault();return false; }   var list = $("#list");// 键盘变化时,隐藏ullist.hide();clearTimeout(this.timer);  //清除延迟执行//设置延迟500毫秒执行this.timer = setTimeout(()=>{// 保存当前数组下标vm.newApproveIndex = index;if(text.length > 0) {// 请求快捷回复内容, 使用回调来处理成功返回的数据getAutoCompletionData(text, function (list) {//后端返回的数据,数据类型为Listvm.autoCompletionData = list;// 触发显示选项框事件, 并绑定单击事件showAutoUI(text, e);});}}, 500);
},

渲染获取到的数据

下面的html是当前业务用到的所有html,其中layui是一个前端开源框架,有需要的可以百度下载,不需要的删除即可。

<!-- 这里是一个大的div -->
<div class="layui-field-box box"><textarea style="margin-top: 10px" class="layui-textarea" v-for="(it, dex) in newApprove" :value="it"
v-model="newApprove[dex]" @keyup="autoCompletion(it, dex, $event)"></textarea><!-- 使用ul-li渲染获取到的自动回复内容 --><ul id="list" ><li id="list_li" v-for="(item, index) in autoCompletionData" :tabindex=index
@click="selectedAutoState(item.optName)">{{item.optName}}                 </li>    </ul> <!-- 用于点击事件,每点击一次增加一个textarea --><div style="text-align: right;"><i v-if="data.xmlJson.isManyApproval" class="layui-icon layui-icon-add-circle" style="font-size: 30px; color:
#1E9FFF;" @click="addApproveDetail()"></i></div>
</div>

获取当前光标位置

获取光标位置需要在监听文本事件,即在showAutoUI(text, e); 方法内部。
以下是showAutoUI方法的代码。第一个参数为变化之后的文本,第二个为当前的点击事件。

function showAutoUI(text, e) {var curTarget = e.target;var list = $("#list");// 获取当前光标所处位置    var position = getPosition(curTarget);   // 光标处于文本最后    if(position === text.length){// 获取当前DOM的所有stylevar iStyle = window.getComputedStyle(curTarget);        //把双字节的替换成两个单字节的然后再获得长度        var len = (text || '').replace(/[^\x00-\xff]/g,"01").length / 2;        var fz = parseFloat(iStyle.fontSize);        var wd = parseFloat(iStyle.width);        var lh = parseFloat(iStyle.lineHeight);        list.css("left", fz * ( len % wd) > wd ? wd : fz * (len % wd) + curTarget.offsetLeft + 5 + "px");        list.css("top", Math.ceil(len / wd) * lh +  curTarget.offsetTop + 5 +"px");list.find("li,.select").each(function({ $(this).removeClass("select")        });list.show();}
}

getPosition即获取光标方法,其中参数为使当前文本改动的DOM,即textarea中拥有光标的那一个。getPosition方法代码如下:

//输入框获取光标
function getPosition(element) {    var cursorPos = 0;    if (document.selection) {//IE        var selectRange = document.selection.createRange();                    selectRange.moveStart('character', -element.value.length);cursorPos = selectRange.text.length;} else if (element.selectionStart || element.selectionStart == '0'{       cursorPos = element.selectionStart;   }    return cursorPos;
}

未完待续~

使用Vue实现文本自动完成(快捷回复)相关推荐

  1. 微信怎么做到快捷回复消息?

    微信聊天回复客户相同的语境和相同类似的话,我们在回答第一次就会输入,第二次有可能输入或者找聊天记录复制修改,第三次.第四次呢还是用相同的办法回复嘛?那样做其实还不是高效率的. 怎么做到更高效的回复呢? ...

  2. 拼多多怎么设置快捷回复

    网购的过程中,买家遇到了问题之后都会第一时间找客服,对于拼多多的商家来说,可以设置快速的自动回复功能来回答一些常见问题.那么拼多多自动回复功能怎么设置呢?下面来教一教大家. 方法: 首先需要进入客服宝 ...

  3. 求qq微信快捷回复软件-微快聊聊天助手小程序

    2021做微商有机会吗?据说99%的人都不知道这微商实用技巧-- 干货|99%的人不知道,原来微商的正确打开模式是酱紫的! 随着电商时代的崛起,如今不少人都从中获取了人生的第一桶金.风靡一时的微商时代 ...

  4. 求一款快捷回复工具聊天辅助软件手机版(聊天微快聊回复助手)

    99%做微商的人都会遇到这个问题,该如何解决? 随着电商时代的快速崛起,许多人已经将微商作为一项全职工作,当然,当中也不乏一些白领人士将其作为副职工作,用以赚取额外收入.而无论是出于什么目的做微商的朋 ...

  5. 微信快捷回复怎么设置?

    微信是一大社交工具之一,很多企业通过微信来运营客户,在微信上与客户做大量的沟通,快捷回复显得尤为重要. 前言 网络时代迅速发展,微信已成为目前一大社交工具之一.很多企业通过微信来运营客户,在微信上和客 ...

  6. 打字速度慢?您需要快捷回复

    客服是隔着屏幕接待客户,因此,打字速度决定了客服响应客户的时间,但如果遇到客户提出重复问题时,客服打字速度再快,也不如快捷回复软件一键发送来的快. 前言 很多从事客服工作的人都想成为一个优秀的客服,不 ...

  7. 聊天话术一键快捷回复,再也不用复制粘贴了!

    经常做生意的朋友,网聊的客户很多,都会有一个烦恼,就是不同的客户总是要回一样的话术,手打实在痛苦,咱这就深有体会啊,苦不堪言啊,第一个客户问过你后第二个客户又问一样的问题,有人就说了,可以复制粘贴呀, ...

  8. VUE 前端文本输出为超文本

    VUE 的前端文本输出为超文本. 但是我们希望的是页面能够自动将超文本进行转换. 问题和解决 {{blogContent.blogContent}} 这种输出方式,VUE 模板是不会将内容以 HTML ...

  9. WhatsApp快捷操作,如何在SendWS拓客系统做到WhatsApp快捷群发筛选,快捷回复,快捷添加好友?

    为什么需要快捷操作? 品牌方或外贸商家利用WhatsApp进行做营销引流推广,能帮助更好的向外国推广品牌,使品牌能成交.在与客户沟通的时候,有时多个客户会问同一个问题或者同时有多个客户提问的时候,如果 ...

最新文章

  1. 靠数学“拿了”两次诺贝尔奖,彭罗斯从“铺地砖”帮忙发现2011年化学奖的秘密...
  2. CentOS系统双网卡路由设置
  3. 四十四、Mysql的命令和PyMysql
  4. [VC]WindowProc和DefWindowProc函数
  5. NET问答: 到底是返回 null 好,还是 空集合 好?
  6. Myeclipse创建第一个web项目
  7. 正确获取Java事件通知
  8. linux编译器项目,编译器架构 LLVM
  9. Java保留小数点一位的方法
  10. D语言/dlang 2.085.0 发布,GC、Objective-C 混编增强
  11. 动手学习数据分析(二)——数据处理
  12. 滴滴 Web 移动端组件库 cube-ui 开源
  13. 51nod 1423 最大二“货” 单调栈
  14. 【交易技术前沿】新一代证券交易系统应用架构的研究
  15. mysql mysqlhotcopy_mysql中mysqlhotcopy备份数据库总结
  16. 如何去掉windows2003的自动锁定(每离开一会都会出现这个界面,不想让它出现)...
  17. 网吧服务器系统介绍,网吧服务器系统
  18. stata 导出 相关系数表_【BBtime】戏说会计论文---stata简单实操
  19. zotero+坚果云安装记录
  20. 把一个字符串13579先变成Array——[1, 3, 5, 7, 9],再利用reduce(),就可以写出一个把字符串转换为Number的函数。

热门文章

  1. 最全spring注解
  2. 文献综述搜索利器——HistCite
  3. 成为优秀的量化交易者,你需要这五种能力
  4. 由于找不到qt5core.dll,无法继续执行代码的问题
  5. 如何在 3 年内摆脱“普通程序员”标签
  6. application-dev.properties
  7. 转载:百为STM32开发板教程之十一——NOR FLASH
  8. 解决el-table锁定列后锁定列对应位置的横向滚动条无法拖动问题
  9. Flink Forward Asia 2022 主论坛概览
  10. 我的脑海里好像是一片空白