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

表情包三种方案

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

  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. 使用CSS选择器(第二部分)

    伪类跟伪元素一样,并不是直接针对文档元素的,而是为你基于某些共同特征选择元素提供方便. 使用结构性伪类选择器 使用结构性伪类选择器能够根据元素在文档中的位置选择元素.这类选择器都有一个冒号字符前缀(: ...

  2. 新一代数据科学ide平台DataSpell提前发行版体验

    1 简介 PyCharm开发公司jetbrains专门面向数据科学的ide项目DataSpell在前不久发布了其EAP版本(早期预览版本),为我们带来了诸多趋于成熟的功能特性,本文就将为大家介绍其使用 ...

  3. netty系列之:让TLS支持http2

    目录 简介 TLS的扩展协议NPN和ALPN SslProvider ApplicationProtocolConfig 构建SslContext ProtocolNegotiationHandler ...

  4. xpath helper插件安装提示程序包无效

    参考链接:https://www.jianshu.com/p/b7d782ef81e0 刚学到爬虫,需要在Chrome浏览器安装xpath helper插件结果一直提示"程序包无效" ...

  5. 【转-Andrew_qian】stm32中断嵌套全攻略

    断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记.废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包 ...

  6. linux centos7 修改默认网卡命名规则为eth0脚本

    CentOS6之前基于传统的命名方式如:eth1,eth0.... Centos7提供了不同的命名规则,默认是基于固件.拓扑.位置信息来分配.这样做的优点是命名是全自动的.可预知的,缺点是比eth0. ...

  7. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  8. 计算机网络之传输层UDP协议

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105453096 学习课程:<2019王道考研计算机网络> 学习目的 ...

  9. MyBatis源码分析(五):MyBatis Cache分析

    一.Mybatis缓存介绍 在Mybatis中,它提供了一级缓存和二级缓存,默认的情况下只开启一级缓存,所以默认情况下是开启了缓存的,除非明确指定不开缓存功能.使用缓存的目的就是把数据保存在内存中,是 ...

  10. CDP客户数据管理平台体系化搭建

    一.Cdp系统简介 1.基本概念 客户数据平台(Customer-Data-Platform),简称CDP:通过采集多方客户数据(主体与线索)等,从而进行精准的客户分析和人群细分,进而实现高效的客户维 ...