From 02b0fa260dfff9e8150cbdfba194c026e2c32e24 Mon Sep 17 00:00:00 2001 From: yuantao Date: Thu, 16 Oct 2025 14:53:26 +0800 Subject: [PATCH] =?UTF-8?q?=20=20feat:=20=E4=BC=98=E5=8C=96=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E5=92=8C=E9=98=B2=E8=AF=AF=E8=A7=A6=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加全局常量DELETE_BUTTON_DELAY(1000ms)统一管理删除按钮延时时间 - 实现删除按钮延时显示机制,防止误触操作 - 调整删除按钮样式尺寸,增大点击区域(40px*40px) - 优化删除按钮显示/隐藏动画过渡效果 - 修复删除按钮事件监听器重复绑定问题 - 完善删除按钮可见性检查逻辑,确保只有可见状态才能执行删除操作 --- src/components/RichTextEditor.vue | 169 ++++++++++++++---------------- 1 file changed, 80 insertions(+), 89 deletions(-) diff --git a/src/components/RichTextEditor.vue b/src/components/RichTextEditor.vue index df72eb8..143c676 100644 --- a/src/components/RichTextEditor.vue +++ b/src/components/RichTextEditor.vue @@ -24,6 +24,9 @@ const props = defineProps({ const emit = defineEmits(['update:modelValue']) +// 全局常量定义 +const DELETE_BUTTON_DELAY = 1000 // 删除按钮延时时间(毫秒),用于防止误触 + const editorRef = ref(null) const content = ref(props.modelValue || '') const isToolbarVisible = ref(false) @@ -111,19 +114,17 @@ onMounted(() => { if (deleteBtn) { // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + container.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 } // 为图片容器添加短按事件以显示/隐藏删除按钮 @@ -925,19 +926,17 @@ const insertImage = () => { // 为删除按钮添加点击事件(鼠标和触摸) // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 // 为图片容器添加短按事件以显示/隐藏删除按钮 let touchStartTime = 0 @@ -1620,19 +1619,17 @@ const wrapOrphanedImages = () => { console.log('Found existing delete button, adding event listeners') // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 // 为图片容器添加短按事件以显示/隐藏删除按钮 // 先移除可能已有的事件监听器,避免重复 @@ -1747,19 +1744,17 @@ const wrapOrphanedImages = () => { // 为删除按钮添加点击事件 // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - imgContainer.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 // 为图片容器添加短按事件以显示/隐藏删除按钮 let touchStartTime = 0 @@ -1896,19 +1891,17 @@ const adjustExistingImages = () => { if (deleteBtn) { // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 } // 为图片容器添加短按事件以显示/隐藏删除按钮 @@ -2061,19 +2054,17 @@ defineExpose({ if (deleteBtn) { // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 } // 为图片容器添加短按事件以显示/隐藏删除按钮 @@ -2195,19 +2186,17 @@ defineExpose({ if (deleteBtn) { // 先移除可能已有的事件监听器,避免重复 deleteBtn.removeEventListener('click', null) - deleteBtn.removeEventListener('touchend', null) - deleteBtn.addEventListener('click', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) - - deleteBtn.addEventListener('touchend', function (e) { - e.stopPropagation() - container.remove() - handleInput() - }) + // 添加延时检查,确保删除按钮是可见的才执行删除操作 + setTimeout(() => { + deleteBtn.addEventListener('click', function (e) { + e.stopPropagation() + if (deleteBtn.classList.contains('visible')) { + imgContainer.remove() + handleInput() + } + }) + }, DELETE_BUTTON_DELAY) // 使用全局常量延时,确保删除按钮状态已正确设置 } // 为图片容器添加短按事件以显示/隐藏删除按钮 @@ -2514,13 +2503,13 @@ defineExpose({ :deep(.editor-content .image-delete-btn) { position: absolute; - top: 8px; - right: 8px; - width: 24px; - height: 24px; + top: 4px; + right: 4px; + width: 40px; + height: 40px; cursor: pointer; z-index: 1000; - transition: opacity 0.2s ease; + transition: opacity calc(v-bind(DELETE_BUTTON_DELAY) / 2 * 1ms) ease; /* 使用背景图片而不是背景色和边框,确保图标正确显示 */ background-image: url('/assets/icons/drawable-xxhdpi/item_image_btn_unbrella_delete.png'); background-size: contain; @@ -2529,11 +2518,13 @@ defineExpose({ background-color: transparent; /* 确保背景透明 */ pointer-events: none; opacity: 0; + display: none; } :deep(.editor-content .image-delete-btn.visible) { pointer-events: all; opacity: 1; + display: block; } :deep(.editor-content .editor-image.draggable) {