网站不备案行吗,建设网站二级建造师如何解聘,做网站需要神,浙江+外贸网站建设在用web端写聊天发送表情的功能中#xff0c;使用web端有系统自带的unicode表情会出现每端不统一的情况#xff0c;不好用不能统一#xff0c;在这里我想到了一个非常好的思路#xff0c;可以解决这个问题#xff01;
那就是发送表情用图片的形式呈现#xff0c;然后发给…在用web端写聊天发送表情的功能中使用web端有系统自带的unicode表情会出现每端不统一的情况不好用不能统一在这里我想到了一个非常好的思路可以解决这个问题
那就是发送表情用图片的形式呈现然后发给后端解析成自定义的编码标识靠这个标识来回显
具体的实现思路是这样的
先编辑好json数据:
{/::1f600::/: {code: /::1f600::/,name: Grinning Face,unified: 1f600,img_url: /static/images/apple_emoji/1f600.png},/::1f603::/: {code: /::1f603::/,name: Smiling Face with Open Mouth,unified: 1f603,img_url: /static/images/apple_emoji/1f603.png},/::1f604::/: {code: /::1f604::/,name: Smiling Face with Open Mouth and Smiling Eyes,unified: 1f604,img_url: /static/images/apple_emoji/1f604.png},
}
这是一个表情包数据里面有图片有name还有标识以键值对的形式/::1f600::/是相当于一个表情包标识
数据处理好了接下来最难的是输入框当我想让表情包在输入框里显示一般的输入框是不行的这里用到了div的contenteditabletrue属性可以让这个div处于编辑模式跟富文本编辑器一样
先展示html:
templatediv classchat-roomdiv classinput-message mt-5 mb-5 scrollbar contenteditabletrue keydownhandleKeyDown blurhandleBlur/div/div
/template
表情包用上面那个json数据展示出来效果图 当我点一下这个表情的时候执行写好的js逻辑把这个表情图片放到div编辑器里代码如下
inputMessage.focus()
var contextMenu document.createElement(img)//创建一个img元素
contextMenu.setAttribute(data-code, value.code) // 添加自定义属性
contextMenu.className emoji-img
contextMenu.style.margin 0 1px
contextMenu.src emojiJSON[value.code] ? emojiJSON[value.code].img_url :
// 获取当前选区
var selection window.getSelection()
if (selection.rangeCount 0) {// 获取选区中的第一个范围var range selection.getRangeAt(0)// 将范围的起点移到插入节点之前range.insertNode(contextMenu)// 创建一个新的范围用于设置光标位置var newRange document.createRange()// 将新范围的起点设置为新插入元素之后newRange.setStartAfter(contextMenu)newRange.collapse(true) // 折叠范围这样光标就会在新插入元素后// 清空当前选区并添加新的范围selection.removeAllRanges()selection.addRange(newRange)
}
// 等待 DOM 更新后滚动到底部
nextTick(() {inputMessage.scrollTop inputMessage.scrollHeight
})
插入表情效果图 给你们看下dom结构 表情跟文字的结合 现在已经实现了文字跟表情在输入框里显示接下来继续处理输入框里面的逻辑实现换行编辑模仿微信的效果
//文本域键盘事件
const handleKeyDown (event) {if (event.ctrlKey event.key Enter) {event.preventDefault() // 阻止默认行为const div document.createElement(div) // 创建一个 div 元素div.setAttribute(data-type, br) // 添加自定义属性const br document.createElement(br) // 创建一个 br 元素div.appendChild(br) // 将 br 元素添加到 div 中const selection window.getSelection()if (selection.rangeCount 0) {const range selection.getRangeAt(0)range.deleteContents() // 删除当前选区内容如果有range.insertNode(div) // 插入换行符range.setStartAfter(div) // 将光标移到换行符之后range.collapse(true) // 折叠选区selection.removeAllRanges() // 清除所有选区selection.addRange(range) // 添加新的选区}// 等待 DOM 更新后滚动到底部nextTick(() {inputMessage.scrollTop inputMessage.scrollHeight})return}if (event.key Enter) {// 在这里执行按下Enter时的操作event.preventDefault() // 阻止默认的回车换行行为sendMessage()}//回退事件if (event.key Enter) {}
}
const handleBlur () {inputMessage.focus()
}
现在实现发送效果这里是核心代码在发送之前先处理一下数据解析成后端可以保存的格式
const sendMessage () {const div document.createElement(div) // 创建一个 div 元素div.innerHTML inputMessage.innerHTML// 使用正则表达式进行替换function replaceNestedDivs(html) {// 定义正则表达式以匹配 div data-typebr.../div 标签并捕获其中的内容和 img 标签如果有的话const regex /div\sdata-typebr(.*?)(img[^]*)?/gi// 使用替换函数对匹配到的内容进行处理return html.replace(regex, function (match, p1, p2) {const content p1 ? p1.trim() : // 去除捕获文本内容的前后空格const imgTag p2 ? ${p2} : // 如果捕获的 img 标签存在则返回空格加上该标签// 返回处理后的内容和 img 标签return \n${content}${imgTag}})}div.innerHTML replaceNestedDivs(div.innerHTML)div.innerHTML div.innerHTML.replace(/img\sdata-code([^])[^]*/g, $1)state.message div.innerText// 如果文本内容不为空则执行提交操作if (state.message) {state.messageList.push({id: 2,content: initMessage(state.message),time: 2024-6-5 15:41,type: system_user,avatar: https://www.wenpblog.com/cdn/static/header/2812.png,})state.message inputMessage.innerHTML initScroll()} else {if (state.sendTipTimeout) {return}state.sendTip truestate.message inputMessage.innerHTML state.sendTipTimeout setTimeout(() {state.sendTip falsestate.sendTipTimeout null}, 1500)}
}//处理聊天数据
const initMessage (text) {// 定义一个函数来将特定格式的字符串替换为图片function replaceWithEmojiImages(text) {// 定义一个正则表达式来匹配 /::1f600::/ 格式的字符串const regex /\/::(.*?)::\//g// 使用 replace 方法和回调函数进行替换return text.replace(regex, (match, p1) {// 构建图片标签const imgSrc ${emojiJSON[match] ? emojiJSON[match].img_url : } // 假设图片存储在这个路径return img data-code${match} src${imgSrc} classemoji-img/})}// 调用函数进行替换const outputText replaceWithEmojiImages(text)return outputText
}
传给后端的解析后数据 /::1f600:://::1f602::/啊是大飒飒的啊是大/::1f60d::/太搞笑 /::1f602::/
注意回显消息的时候需要用v-html去显示
最终效果图