行业知识
前端聊天怎么实现艾特@功能?高亮@信息,仿微信、qq艾特功能
2026-11-12 22:39:09
来源:互联网转载
此demo使用vue3
实现效果图
声明:这只是个demo,不涉及与后端交互,不过会在该交互的地方标记,如需实际应用于项目,请根据实际情况进行改造完善!
艾特列表组件定义
- {{ user.name }}
showAtSelect.value = false;}, 100);隐藏艾特组件)
// 输入框输入事件function msgInputFun(e) { if (e.data === "@") { setTimeout(() => { const { x, y } = getCursorPosition(); showAtSelect.value = true; userGroupPosition.x = x + "px"; userGroupPosition.y = y + "px"; }, 100); } else { showAtSelect.value = false; }}// 获取输入框中的光标相对页面的坐标function getCursorPosition() { let sel = window.getSelection(); let range = document.createRange(); range.selectNode(sel.focusNode); range.setStart(sel.focusNode, sel.focusOffset); const { x, y } = range.getBoundingClientRect(); return { x, y };} 这个时候可以显示出来群员选择列表了,再来定义键盘事件,在列表组件显示时阻止上下按钮的默认行为。如果不显示且按下回车时发送消息
// 显示艾特选择组件时,阻止输入框默认上下按键及回车行为function msgInputKeyDown(e) { if (showAtSelect.value && ["ArrowUp", "ArrowDown", "Enter"].includes(e.key)) { return e.preventDefault(); } if (e.key === "Enter") { e.preventDefault(); sendMsg(); }} 然后编写选择群员事件,先获取并设置输入框选区,创建一个span标签节点,把被艾特人相关信息填入后插入到输入框子节点里。注意:创建的span标签里写了一个@,所以需要chatInputOffset.deleteContents()删除原@字符
function selectAtUser(user) { showAtSelect.value = false; msgInput.value.blur(); getInputSelection(); chatInputOffset.setStart(focusNode, focusOffset.value - 1); chatInputOffset.setEnd(focusNode, focusOffset.value); chatInputOffset.deleteContents(); const atElement = `${user.id}' userName='${user.name}' contentEditable="false" >@${user.name} `; chatInputOffset.collapse(false); const node = chatInputOffset.createContextualFragment(atElement); let c = node.lastChild; chatInputOffset.insertNode(node); if (c) { chatInputOffset.setEndAfter(c); chatInputOffset.setStartAfter(c); } let j = window.getSelection(); j.removeAllRanges(); j.addRange(chatInputOffset);} 这个时候就可以把@消息发送出去了
let msgType = ref("text"); // 发送的消息类型function sendMsg() { console.log("msgInput:", msgInput); chatMsgRecord.value = ""; // 先清空一下旧消息 msgType.value = "text"; // 初始化消息类型 msgInput.value.childNodes.forEach((element) => { // 如果是emoji表情图片的话,则转义 if (element.nodeName === "IMG" && element.className === "emoji") { chatMsgRecord.value += element.alt; } else if (element.className === "at-msg") { chatMsgRecord.value += element.innerText + " "; msgType.value = "groupChatAt"; // 根据实际约束类型修改 } else { chatMsgRecord.value += element.data; } }); // 清空输入框中的内容 msgInput.value.innerHTML = ""; msgInput.value.innerText = ""; // 在这里使用websocket把数据发送给后端 // socketSend({text:chatMsgRecord,type:msgType})} 如有更好的意见欢迎在评论区指出!
上一篇:怎么样查找网站服务器?
下一篇:服务器 端口在哪里?