项目需求是这样的:要求实现类似于微信聊天一样,表情+文字效果 “文字效果”

表情包三种方案

表情包的实现其实可以分为以下三种情况:

  1. 表情包:点击表情--直接发送大表情(这种方案其实就是发送了一张定义好的图片而已)
  2. emoji图标表情:系统可识别的emoji图标表情,这种表情实现起来相对麻烦一些,其实这种方法emoji我们可以当成一个2位字符的特殊文字去处理
    • 推荐emoji网址:emojis

      • 案例:禾蛙招聘网站
  3. 自定义表情:一版是设计画好的,需要我们实现文字+表情进行发送和回显的
    • 思路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、实现

这里实现思路包括三个方向:

  1. 添加表情,添加文字
  2. 获取输入的消息内容,传递给后端
  3. 拿到特殊消息体'[微笑]',渲染对应的表情

添加表情,添加文字

输入文字:单纯的输入文字其实很简单,思路就是可编辑区域可输入对应的文本内容

添加表情:实现思路是,再点击添加表情时就是讲表情地址生成<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实现聊天+图片表情功能的更多相关文章

  1. vue项目中图片预览旋转功能

    最近项目中需要在图片预览时,可以旋转图片预览,在网上找了下,发现有一款功能强大的图片组件:viewerjs. git-hup: https://github.com/fengyuanchen/view ...

  2. [Asp.net 开发系列之SignalR篇]专题三:使用SignalR实现聊天室的功能

    一.引言 在前一篇文章中,我向大家介绍了如何实现实现端对端聊天的功能的,在这一篇文章中将像大家如何使用SignalR实现群聊这样的功能. 二.实现思路 要想实现群聊的功能,首先我们需要创建一个房间,然 ...

  3. Android表情功能

    Android表情功能 标签(空格分隔): 未分类 转载自:android edittext插入表情(基于socket方式),并对文中不正确的内容进行整理和修正 [TOC] 涉及知识点: Androi ...

  4. android 新浪微博客户端的表情功能的实现

    这是一篇好文章,我转来收藏,技术的最高境界是分享. 最近在搞android 新浪微博客户端,有一些心得分享弄android客户端表情功能可以用以下思路1.首页把新浪的表情下载到本地一文件夹种,表情图片 ...

  5. WPF仿QQ聊天框表情文字混排实现

    原文:WPF仿QQ聊天框表情文字混排实现 二话不说.先上图 图中分别有文件.文本+表情.纯文本的展示,对于同一个list不同的展示形式,很明显,应该用多个DataTemplate,那么也就需要Data ...

  6. Vue实现一个图片懒加载插件(转载)

    Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: &l ...

  7. Vue PC端图片预览插件

    *手上的项目刚刚搞完了,记录一下项目中遇到的问题,留做笔记: 需求: 在项目中,需要展示用户上传的一些图片,我从后台接口拿到图片url后放在页面上展示,因为被图片我设置了宽度限制(150px),所以图 ...

  8. VUE+Element 前端应用开发框架功能介绍

    前面介绍了很多ABP系列的文章<ABP框架使用>,一步一步的把我们日常开发中涉及到的Web API服务构建.登录日志和操作审计日志.字典管理模块.省份城市的信息维护.权限管理模块中的组织机 ...

  9. iOS开发UI篇—UIScrollView控件实现图片缩放功能

    iOS开发UI篇—UIScrollView控件实现图片缩放功能 一.缩放 1.简单说明: 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对 ...

随机推荐

  1. 微信小程序内判断是否关注公众号(JAVA)

    微信小程序内判断是否关注公众号(JAVA) 思路来源(第二种): https://blog.csdn.net/Yanheeee/article/details/117295643 /** * 总体思路 ...

  2. 网络协议之:加密传输中的NPN和ALPN

    目录 简介 SSL/TLS协议 NPN和ALPN 交互的例子 总结 简介 自从HTTP从1.1升级到了2,一切都变得不同了.虽然HTTP2没有强制说必须使用加密协议进行传输,但是业界的标准包括各大流行 ...

  3. 5分钟让你掌握Vuex,深入浅出

    5分钟让你掌握Vuex,深入浅出 一.什么是Vuex? 概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预 ...

  4. 洛谷 P4774 [NOI2018] 屠龙勇士

    链接:P4774 前言: 交了18遍最后发现是多组数据没清空/ll 题意: 其实就是个扩中. 分析过程: 首先发现根据题目描述的选择剑的方式,每条龙对应的剑都是固定的,有查询前驱,后继(在该数不存在前 ...

  5. 转帖:新版vivado2019.2新增增量综合功能

    从 Vivado 2019.1 版本开始,Vivado 综合引擎就已经可以支持增量流程了.这使用户能够在设计变化较小时减少总的综合运行时间. Vivado IDE 和 Tcl 命令批处理模式都可以启用 ...

  6. js实现日期格式化封装--八种

    封装一个momentTime.js文件,包含8种格式. 需要传两个参数: 时间戳:stamp 格式化的类型:type, 日期补零的方法用到es6语法中的padStart(length,'字符'): 第 ...

  7. CentOS7 导入oracle数据

    1.切换到 oracle用户 #su - oracle 2.导入(一般的不会导入到sys账号下) #imp sys/密码@orcl file=/home/oracle/20200428.dmp fro ...

  8. 【Azure 存储服务】代码版 Azure Storage Blob 生成 SAS (Shared Access Signature: 共享访问签名)

    问题描述 在使用Azure存储服务,为了有效的保护Storage的Access Keys.可以使用另一种授权方式访问资源(Shared Access Signature: 共享访问签名), 它的好处可 ...

  9. robot_framewok自动化测试--(2)创建第一个项目

    创建第一个robot_framewok项目 通过 RIDE 去学习和使用 Robot Framework 框架,对于初学者来说大大的降低了学习难度.所以后面对 Robot Framework 框架都将 ...

  10. 【Python+postman接口自动化测试】(6)Chrome开发者工具

    Chrome开发者工具 Elements: HTML元素面板,用于定位查看元素源代码 Console: js控制台面板,js命令行,查看前端日志 Sources: 资源面板,用于断点调试js Netw ...