vue实现聊天+图片表情功能
2021-11-24 13:12
381 查看
项目需求是这样的:要求实现类似于微信聊天一样,表情+文字效果 “文字效果😀😀😀”
表情包三种方案
表情包的实现其实可以分为以下三种情况:
- 表情包:点击表情--直接发送大表情(这种方案其实就是发送了一张定义好的图片而已)
- emoji图标表情:系统可识别的emoji图标表情,这种表情实现起来相对麻烦一些,其实这种方法emoji我们可以当成一个2位字符的特殊文字去处理
-
推荐emoji网址:emojis
案例:禾蛙招聘网站
- 自定义表情:一版是设计画好的,需要我们实现文字+表情进行发送和回显的
-
思路1:我们在点击单个表情的时候输入框内需要添加表情,这是输入框内表情可以用‘[微笑]‘这种方式代替。只有在回显的时候去识别特殊表示,再用表情去替换掉即可
案例:BOSS直聘网站
- 思路2:输入框也需要是表情的回显,这种方法就相对麻烦了一些
-
案例:微信客户端
实现
这里针对自定义表情包的思路2,进行实现,个人认为也是最麻烦的实现 实现效果 这里只针对输入框进行实现,对于数据传递给后端,消息的回显这里就不进行阐述了,想必大家也有自己更好的设计方法。
1、布局
大家可能会想到输入区域可以用用input,或者是textarea标签,但针对‘文字+自定义图片表情’是不太适用的,不过对于其他的实现方案还是可行的。 实现思路
- 采用
div+ contenteditable="true"
属性 举例:'这是一个可编辑段落。
'
contenteditable属性:
- 属性指定元素内容是否可编辑。
- 所有主流浏览器都支持 contenteditable 属性
- 设置了true:该标签默认就存在了@fcous,@input等事件函数
- 注意: 当元素中没有设置 contenteditable 属性时,元素将从父元素继承。
值 | 描述 |
---|---|
true | 指定元素是可编辑的 |
false | 指定元素是不可编辑的 |
<div id="emojiText" contenteditable="true" ref="edit" placeholder="请输入内容" ></div>
2、实现
这里实现思路包括三个方向:
- 添加表情,添加文字
- 获取输入的消息内容,传递给后端
- 拿到特殊消息体'[微笑]',渲染对应的表情
添加表情,添加文字 输入文字:单纯的输入文字其实很简单,思路就是可编辑区域可输入对应的文本内容 添加表情:实现思路是,再点击添加表情时就是讲表情地址生成
<img>标签插入到可编辑区域内 添加表情存在的问题: 问题1:添加表情时光标不会聚焦到可编辑区域 问题2:添加表情无法添加到光标定位的位置上 问题1解决方案 添加表情时检查是否聚焦,无聚焦执行fcous强制聚焦
let obj = this.$refs.edit; // obj 是可编辑的div let range, node; if (!obj.hasfocus) { obj.focus(); }
问题2解决方案 window.getSelection:选择的文本范围或光标的当前位置。 getRangeAt 返回选区开始的节点(Node)。 因为通常情况下用户只能选择一个范围,所以只有一个选区(range),此方法一般为getRangeAt(0)
range = window.getSelection().getRangeAt(0); range.collapse(false); //光标移至最后 node = range.createContextualFragment(Img); let c = node.lastChild; range.insertNode(node); if (c) { range.setEndAfter(c); range.setStartAfter(c); } let j = window.getSelection(); j.removeAllRanges(); j.addRange(range);
完整代码
<template> <div> <div id="emojiText" contenteditable="true" ref="edit" placeholder="请输入内容" ></div> <ul> <li v-for="item in emojis" :key="item.name"> <img :src="item.path" alt="" @click="getEmojis" /> </li> </ul> <button @click="senMsg">发送</button> </div> </template> <script> export default { components: {}, data() { return { emojis: [ { name: "[emoji-1]", path: require("./assets/emojis/m1.png"), }, { name: "[微笑]", path: require("./assets/emojis/m2.png"), }, { name: "[emoji-3]", path: require("./assets/emojis/m3.png"), }, ], }; }, mounted() {}, methods: { getEmojis(event) { let Img = `<img src="${event.target.src}" style='height:10px;'>`; let obj = this.$refs.edit; // obj 是可编辑的div let range, node; if (!obj.hasfocus) { obj.focus(); }/* window.getSelection:选择的文本范围或光标的当前位置。 getRangeAt 返回选区开始的节点(Node)。 因为通常情况下用户只能选择一个范围,所以只有一个选区(range),此方法一般为getRangeAt(0) */ if (window.getSelection && window.getSelection().getRangeAt) { range = window.getSelection().getRangeAt(0); range.collapse(false); //光标移至最后 node = range.createContextualFragment(Img); let c = node.lastChild; range.insertNode(node); if (c) { range.setEndAfter(c); range.setStartAfter(c); } let j = window.getSelection(); j.removeAllRanges(); j.addRange(range);} else if (document.selection && document.selection.createRange) { document.selection.createRange().pasteHTML(Img); } }, senMsg() { console.log(this.$refs.edit.innerHTML); }, natchMsg() { let str = "比如‘[微笑]’asdtgsaghd[微笑]ggg"; let newStr = str; this.emojis.forEach((item) => { console.log(str.indexOf(item.name)); if (str.indexOf(item.name) > -1) { let Img = `<img src="${item.path}" style='height:10px;'>`; newStr = str.replaceAll(item.name, Img); } }); console.log(newStr); }, }, }; </script> <style lang='scss' scoped> #emojiText { width: 600px; height: 300px; border: 1px solid #111; } ul { display: flex; list-style: none; } li img { width: 20px; height: 20px; } .msgicon { width: 10px; height: 10px; } </style> ``
相关文章推荐
- 继人员列表,聊天的实现,包括图片,语音,位置,表情
- vue实现的上传图片到数据库并显示到页面功能示例
- vue+elementUI实现表单和图片上传及验证功能示例
- 基于node+vue实现简单的WebSocket聊天功能
- 微信小程序实现聊天对话(文本、图片)功能
- vue+elementUI实现图片上传功能
- 基于vue+ bootstrap实现图片上传图片展示功能
- 继人员列表,聊天的实现,包括图片,语音,位置,表情
- vue实现的上传图片到数据库并显示到页面功能示例
- android 轻松实现在线即时聊天【图片、语音、表情、文字】等!含源码!
- 在Flex中实现聊天表情图片支持-资料篇
- vue实现裁切图片同时实现放大、缩小、旋转功能
- vue+element-ui 实现上传前图片压缩功能
- 移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
- 基于vue-simplemde实现图片拖拽、粘贴功能
- vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
- 实现简单的聊天功能部分Vue
- 移动端Vue下使用Cropper.js + 原生js实现图片裁剪异步上传功能
- android 轻松实现在线即时聊天【图片、语音、表情、文字】等!含源码!
- 详解vue项目中实现图片裁剪功能