refactor(editor): 优化mention处理逻辑并移除调试日志
移除调试用的console.log语句 重构mention列表过滤逻辑,使用startsWith替代includes 添加Backspace和Delete键删除mention元素的功能 优化键盘事件处理逻辑,减少不必要的DOM操作
This commit is contained in:
parent
047cea20b9
commit
628894a254
@ -33,7 +33,6 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['editor-event'])
|
||||
|
||||
// 响应式数据
|
||||
const editorRef = ref(null)
|
||||
const content = ref('')
|
||||
const isFocused = ref(false)
|
||||
@ -49,7 +48,6 @@ const fileImageRef = ref(null)
|
||||
const uploadFileRef = ref(null)
|
||||
const emoticonRef = ref(null)
|
||||
|
||||
// 获取状态管理
|
||||
const dialogueStore = useDialogueStore()
|
||||
const editorDraftStore = useEditorDraftStore()
|
||||
|
||||
@ -94,7 +92,7 @@ const toolbarConfig = computed(() => {
|
||||
return config
|
||||
})
|
||||
|
||||
// 处理输入事件 - 优化版本,减少DOM操作
|
||||
// 处理输入事件
|
||||
const handleInput = (event) => {
|
||||
const target = event.target
|
||||
|
||||
@ -162,9 +160,9 @@ const checkMention = (target) => {
|
||||
// 显示mention列表
|
||||
const showMentionList = () => {
|
||||
const query = currentMentionQuery.value.toLowerCase()
|
||||
mentionList.value = props.members.filter(member =>
|
||||
member.nickname.toLowerCase().includes(query)
|
||||
).slice(0, 10)
|
||||
mentionList.value = props.members.filter(member => {
|
||||
return member.value.toLowerCase().startsWith(query)
|
||||
})
|
||||
|
||||
showMention.value = mentionList.value.length > 0
|
||||
selectedMentionIndex.value = 0
|
||||
@ -310,7 +308,7 @@ const handlePaste = (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理键盘事件 - 优化版本,减少不必要的日志和简化逻辑
|
||||
// 处理键盘事件
|
||||
const handleKeydown = (event) => {
|
||||
// 处理@提及列表的键盘导航
|
||||
if (showMention.value) {
|
||||
@ -358,6 +356,122 @@ const handleKeydown = (event) => {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理删除键(Backspace和Delete)删除mention元素
|
||||
if (event.key === 'Backspace' || event.key === 'Delete') {
|
||||
const selection = window.getSelection()
|
||||
if (!selection.rangeCount) return
|
||||
|
||||
const range = selection.getRangeAt(0)
|
||||
const editor = editorRef.value
|
||||
|
||||
// 只处理光标位置的删除,不处理选中内容的删除
|
||||
if (range.collapsed) {
|
||||
let targetMention = null
|
||||
|
||||
// 获取光标位置信息
|
||||
const container = range.startContainer
|
||||
const offset = range.startOffset
|
||||
|
||||
if (event.key === 'Backspace') {
|
||||
// Backspace:查找光标前面的mention元素
|
||||
if (container.nodeType === Node.TEXT_NODE) {
|
||||
// 如果光标在文本节点的开头,检查前一个兄弟节点
|
||||
if (offset === 0) {
|
||||
let prevSibling = container.previousSibling
|
||||
while (prevSibling) {
|
||||
if (prevSibling.nodeType === Node.ELEMENT_NODE &&
|
||||
prevSibling.classList &&
|
||||
prevSibling.classList.contains('mention')) {
|
||||
targetMention = prevSibling
|
||||
break
|
||||
}
|
||||
// 如果是文本节点且不为空,停止查找
|
||||
if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
|
||||
break
|
||||
}
|
||||
prevSibling = prevSibling.previousSibling
|
||||
}
|
||||
}
|
||||
} else if (container.nodeType === Node.ELEMENT_NODE) {
|
||||
// 如果光标在元素节点中,检查前一个子节点
|
||||
if (offset > 0) {
|
||||
let prevChild = container.childNodes[offset - 1]
|
||||
// 如果前一个子节点是mention元素
|
||||
if (prevChild && prevChild.nodeType === Node.ELEMENT_NODE &&
|
||||
prevChild.classList && prevChild.classList.contains('mention')) {
|
||||
targetMention = prevChild
|
||||
}
|
||||
// 如果前一个子节点是文本节点,检查它前面的兄弟节点
|
||||
else if (prevChild && prevChild.nodeType === Node.TEXT_NODE && !prevChild.textContent.trim()) {
|
||||
let prevSibling = prevChild.previousSibling
|
||||
while (prevSibling) {
|
||||
if (prevSibling.nodeType === Node.ELEMENT_NODE &&
|
||||
prevSibling.classList &&
|
||||
prevSibling.classList.contains('mention')) {
|
||||
targetMention = prevSibling
|
||||
break
|
||||
}
|
||||
if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
|
||||
break
|
||||
}
|
||||
prevSibling = prevSibling.previousSibling
|
||||
}
|
||||
}
|
||||
} else if (offset === 0 && container === editor) {
|
||||
// 特殊情况:光标在编辑器开头,检查第一个子节点是否是mention
|
||||
const firstChild = container.firstChild
|
||||
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE &&
|
||||
firstChild.classList && firstChild.classList.contains('mention')) {
|
||||
targetMention = firstChild
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (event.key === 'Delete') {
|
||||
// Delete:查找光标后面的mention元素
|
||||
if (container.nodeType === Node.TEXT_NODE) {
|
||||
// 如果光标在文本节点的末尾,检查后一个兄弟节点
|
||||
if (offset === container.textContent.length) {
|
||||
let nextSibling = container.nextSibling
|
||||
while (nextSibling) {
|
||||
if (nextSibling.nodeType === Node.ELEMENT_NODE &&
|
||||
nextSibling.classList &&
|
||||
nextSibling.classList.contains('mention')) {
|
||||
targetMention = nextSibling
|
||||
break
|
||||
}
|
||||
// 如果是文本节点且不为空,停止查找
|
||||
if (nextSibling.nodeType === Node.TEXT_NODE && nextSibling.textContent.trim()) {
|
||||
break
|
||||
}
|
||||
nextSibling = nextSibling.nextSibling
|
||||
}
|
||||
}
|
||||
} else if (container.nodeType === Node.ELEMENT_NODE) {
|
||||
// 如果光标在元素节点中,检查后一个子节点
|
||||
if (offset < container.childNodes.length) {
|
||||
const nextChild = container.childNodes[offset]
|
||||
if (nextChild && nextChild.nodeType === Node.ELEMENT_NODE &&
|
||||
nextChild.classList && nextChild.classList.contains('mention')) {
|
||||
targetMention = nextChild
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找到了要删除的mention元素
|
||||
if (targetMention) {
|
||||
event.preventDefault()
|
||||
|
||||
// 删除mention元素
|
||||
targetMention.remove()
|
||||
|
||||
// 触发输入事件更新编辑器内容
|
||||
handleInput({ target: editor })
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理Ctrl+Enter或Shift+Enter换行
|
||||
if (event.key === 'Enter' && (event.ctrlKey || event.metaKey || event.shiftKey)) {
|
||||
// 手动插入换行符
|
||||
@ -402,7 +516,7 @@ const handleKeydown = (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 发送消息 - 优化版本,移除不必要的日志,简化逻辑
|
||||
// 发送消息
|
||||
const sendMessage = () => {
|
||||
// 解析编辑器内容
|
||||
const messageData = parseEditorContent()
|
||||
|
@ -16,8 +16,6 @@ import avatarModule from '@/components/avatar-module/index.vue'
|
||||
const userStore = useUserStore()
|
||||
const dialogueStore = useDialogueStore()
|
||||
const uploadsStore = useUploadsStore()
|
||||
console.log('dialogueStore', dialogueStore)
|
||||
|
||||
const members = computed(() => dialogueStore.members)
|
||||
const membersByAlphabet = computed(() => {
|
||||
if (state.searchMemberByAlphabet) {
|
||||
|
Loading…
Reference in New Issue
Block a user