遇到难题,保持平常心,勇于面对,总会找出突破口。
前言
有这样一个场景: 实现了文字和图片的混输,此时div中有img标签和文字,那么我们要将这些内容发送给服务端,然后服务端将我们发送的内容推送给每个用户,服务端需要什么格式的数据?我们客户端拿到服务端返回的数据,要怎么渲染到页面?接下来就给大家分享下我的解决方案,先给大家看一下最终实现的效果
实现思路
- 监听回车事件
- 获取输入框的所有子元素
- 遍历所有子元素
- 找出img标签和text节点
- 获取img标签的alt标识,将alt标识解析成特定字符串
- 调用接口发送最终解析好的字符串
- 获取接口返回的数据,解析自定义标识符
- 获取自定义标识符在字符串中出现的位置,将其解析成img标签
- 渲染解析好的字符串
实现过程
- 监听回车事件
<div class="input-panel" ref="msgInputContainer"@keydown.enter.exact="sendMessage($event)" contenteditable="true" spellcheck="false"></div>
- 实现回车事件函数
sendMessage: function (event) {
if (event.keyCode === 13) {
// 阻止编辑框默认生成div事件
event.preventDefault();
let msgText = "";
// 获取输入框下的所有子元素
let allNodes = event.target.childNodes;
for(let item of allNodes){
// 判断当前元素是否为img元素
if(item.nodeName==="IMG"){
msgText += `/${item.alt}/`;
}
else{
// 获取text节点的值
if(item.nodeValue!==null){
msgText += item.nodeValue;
}
}
}
console.log("消息捕获成功:");
console.info(msgText);
// 接口调用,发送消息至服务端
// 此处省略...
//
// 解析接口返回的数据进行渲染
/**
* 使用正则表达式解析特定字符串
* 找到特定字符串出现的位置
* 遍历配置文件中的json数据,
* 判断当前关键字是否在配置文件中
* 获取配置文件中的属性,生成img标签
* 替换特定字符串为所生成的img标签
* */
let separateReg = /(\/[^/]+\/)/g;
let finalMsgText = "";
// 将符合条件的字符串放到数组里
const resultArray = msgText.match(separateReg);
if(resultArray!==null){
for (let item of resultArray){
// 删除字符串中的/符号
item = item.replace(/\//g,"");
for (let emojiItem of this.emojiList){
// 判断捕获到的字符串与配置文件中的字符串是否相同
if(emojiItem.info === item){
const imgSrc = require(`../assets/img/emoji/${emojiItem.hover}`);
const imgTag = `<img src="${imgSrc}" width="28" height="28" alt="${item}">`;
// 替换匹配的字符串为img标签
finalMsgText = msgText.replace(separateReg,imgTag);
}
}
}
}else{
finalMsgText = msgText;
}
console.log("消息解析成功:");
console.log(finalMsgText);
const thisSenderMessageObj = {
"msgText": finalMsgText,
"msgId": Date.parse(new Date()),
"avatarSrc": require("../assets/img/avatar.jpg")
};
// 渲染页面
this.senderMessageList.push(thisSenderMessageObj);
// 清空输入框中的内容
event.target.innerHTML = "";
}
},
踩坑记录
-
使用removeChild()、innerHTML删除可编辑div的子元素
获取他的所有子元素,进行遍历删除,但是就是删不掉回车所产生的div,也不知道是不是自己写错了,有发现错误的朋友,欢迎评论区留言指正。
let allNodes = event.target.childNodes; // 清空输入框中的内容 for (let nodesItem of allNodes){ event.target.removeChild(nodesItem); } // event.target.innerHTML = "";
-
错误的正则表达式
在渲染解析好的文字和图片的混输内容时,要将/图片描述/转成img标签,看了好久的正则表达式文档研究出的写法,看似没问题实则用不了。最后在群里求助,遇到了一个正则大佬,帮我改进了下,最终实现了我的需求
// 我的正则 let separateReg = /^\/.*\/$/g; // 大佬帮我改进的正则 let separateReg = /(\/[^/]+\/)/g;
-
正确的删除可编辑div中的子元素
先禁用掉可编辑div的回车生成div事件,然后清空输入框的内容
javascript event.preventDefault(); event.target.innerHTML = "";
-
正确解析字符串dom
v-html的妙用
html <p v-html="item.msgText"/>
写在最后
- 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
- 本文首发于掘金,如需转载请评论区留言💌