背景:
网页需要显示和发送带 emoji 表情的文本消息(为方便理解, 以 whatsapp 为例, 实际开发中待定)
同时, 要求不同系统打开网页时, 看到的都是同一套 emoji , 避免同一个 emoji 在不同电脑上显示不同
概述:
- 引入 twemoji 库文件
- 把网页版 wa 的 emoji 全部复制下来
- 新增 emoji 组件, 点击表情图标弹出表情框, 框内显示与 wa 一致
- 点选框中表情, 根据点击前光标在输入框(contentEditable 的 div)的位置, 插入 twemoji.parse 转换过的表情(图片)
- 给各处可能显示 twemoji 的 div 加上特定 class(比如 twemoji-convert), 在程序主界面(Main.vue)新增 MutationObserver , 在 DOM 变化时选取此类 class 元素, 使用 twemoji.parse 转换元素, 使显示 emoji
实现过程:
-
引入 twemoji
<!-- Start twemoji 库文件 --> <script src="https://twemoji.maxcdn.com/v/13.1.0/twemoji.min.js" integrity="sha384-gPMUf7aEYa6qc3MgqTrigJqf4gzeO6v11iPCKv+AP2S4iWRWCoWyiR+Z7rWHM/hU" crossorigin="anonymous"></script> <!-- End twemoji 库文件 -->
-
复制 wa emoji
在网页版 whatsapp 上聊天, 一栏栏地点选表情, 发送, 复制下来, 此时接收到的内容已经是字符了, 把这些字符按顺序提取为数组;
这个需要耐心, 这些个字符千奇百怪, 有的字符电脑系统不支持不能渲染出来, 有的字符后面需要接一个空格, 有的字符看上去只有一位但实际占了多位, 最多的还是由多种字符组合显示成一个表情的(字符人, 可加修饰字符: 性别, 发型, 职业, with another one …), 千万别弄错了
-
新增 emoji 组件
渲染表情部分由全局的 MutationObserver 负责(twemoji.parse)
选中表情部分如下:
// 点击选中 emoji handleClickEmoji(e) { // 取选中的 emoji DOM 标签 let emojiImg; if (e.target.classList.contains('emoji-item')) { emojiImg = e.target.querySelector('img.emoji'); } else if (e.target.classList.contains('emoji')) { emojiImg = e.target; } // 取标签上的 alt (实体字符, twemoji 转换后自带)传给外部 if (emojiImg) { this.$emit('checkEmoji', emojiImg.getAttribute('alt')); } }
-
输入框接收选中表情, 加入到输入框中
输入框 div
<!-- 因为正常 textarea 无法显示 emoji img , 现在将输入框改为 contentEditable div --> <div :contentEditable="true" ref="sendMsg" @click="save_range" @keyup="save_range" @keydown="inputOnKeyDown" @paste