You've already forked SmartisanNote.Remake
优化 调整了编辑器中的工具栏显示隐藏逻辑
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div class="editor-container">
|
||||
<!-- 工具栏 -->
|
||||
<div class="toolbar" :class="{ visible: isToolbarVisible }" @mousedown.prevent @focusin="keepToolbarVisible" @focusout="handleToolbarFocusOut">
|
||||
<div class="toolbar" :class="{ visible: isToolbarVisible, 'keyboard-visible': isKeyboardVisible, 'dynamic-position': isKeyboardVisible }" @mousedown.prevent @focusin="keepToolbarVisible" @focusout="handleToolbarFocusOut">
|
||||
<button v-for="tool in tools" :key="tool.name" :class="{ active: tool.active }" @click.stop="handleToolClick(tool.action, $event)" @mousedown.prevent @focusout.prevent class="toolbar-btn">
|
||||
<img :src="tool.icon" :alt="tool.name" class="toolbar-icon" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 编辑区域 -->
|
||||
<div ref="editorRef" contenteditable="true" class="editor-content" @input="handleInput" @keydown="handleKeydown" @click="updateToolbarState" @keyup="updateToolbarState" @focus="showToolbar" @blur="hideToolbar"></div>
|
||||
<div ref="editorRef" contenteditable="true" class="editor-content" @input="handleInput" @keydown="handleKeydown" @click="updateToolbarState" @keyup="updateToolbarState" @focus="showToolbar" @blur="handleBlur"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@@ -27,6 +27,8 @@ const emit = defineEmits(['update:modelValue'])
|
||||
const editorRef = ref(null)
|
||||
const content = ref(props.modelValue || '')
|
||||
const isToolbarVisible = ref(false)
|
||||
const isKeyboardVisible = ref(false)
|
||||
const initialViewportHeight = ref(0)
|
||||
|
||||
// 初始化编辑器内容
|
||||
onMounted(() => {
|
||||
@@ -48,6 +50,28 @@ onMounted(() => {
|
||||
console.log('Editor initialized without initial content')
|
||||
}
|
||||
}
|
||||
|
||||
// 记录初始视口高度
|
||||
initialViewportHeight.value = window.visualViewport?.height || window.innerHeight
|
||||
|
||||
// 初始化CSS变量
|
||||
document.documentElement.style.setProperty('--viewport-height', `${initialViewportHeight.value}px`)
|
||||
|
||||
// 添加虚拟键盘检测事件监听器
|
||||
if (window.visualViewport) {
|
||||
window.visualViewport.addEventListener('resize', handleViewportResize)
|
||||
} else {
|
||||
window.addEventListener('resize', handleWindowResize)
|
||||
}
|
||||
})
|
||||
|
||||
// 组件卸载时移除事件监听器
|
||||
onUnmounted(() => {
|
||||
if (window.visualViewport) {
|
||||
window.visualViewport.removeEventListener('resize', handleViewportResize)
|
||||
} else {
|
||||
window.removeEventListener('resize', handleWindowResize)
|
||||
}
|
||||
})
|
||||
|
||||
// 工具栏配置
|
||||
@@ -718,6 +742,67 @@ const updateToolbarState = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 处理视口大小变化(用于检测虚拟键盘)
|
||||
const handleViewportResize = () => {
|
||||
if (!window.visualViewport) return
|
||||
|
||||
const currentHeight = window.visualViewport.height
|
||||
const heightDifference = initialViewportHeight.value - currentHeight
|
||||
|
||||
// 如果高度差超过150px,认为虚拟键盘已弹出
|
||||
isKeyboardVisible.value = heightDifference > 150
|
||||
|
||||
// 动态设置CSS变量以调整工具栏位置
|
||||
document.documentElement.style.setProperty('--viewport-height', `${currentHeight}px`)
|
||||
|
||||
// 根据虚拟键盘状态更新工具栏可见性
|
||||
updateToolbarVisibility()
|
||||
}
|
||||
|
||||
// 处理窗口大小变化(备用方案)
|
||||
const handleWindowResize = () => {
|
||||
const currentHeight = window.innerHeight
|
||||
const heightDifference = initialViewportHeight.value - currentHeight
|
||||
|
||||
// 如果高度差超过150px,认为虚拟键盘已弹出
|
||||
isKeyboardVisible.value = heightDifference > 150
|
||||
|
||||
// 根据虚拟键盘状态更新工具栏可见性
|
||||
updateToolbarVisibility()
|
||||
}
|
||||
|
||||
// 更新工具栏可见性
|
||||
const updateToolbarVisibility = () => {
|
||||
// 只有当编辑器有焦点且虚拟键盘可见时才显示工具栏
|
||||
if (isKeyboardVisible.value && (document.activeElement === editorRef.value || isTodoContentActive())) {
|
||||
isToolbarVisible.value = true
|
||||
} else {
|
||||
// 延迟隐藏工具栏,确保用户有时间操作
|
||||
setTimeout(() => {
|
||||
// 只有在没有待办事项获得焦点且虚拟键盘不可见时才隐藏工具栏
|
||||
if (!isTodoContentActive() && !isKeyboardVisible.value) {
|
||||
isToolbarVisible.value = false
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否有待办事项内容区域获得焦点
|
||||
const isTodoContentActive = () => {
|
||||
const todoContentElements = document.querySelectorAll('.todo-content')
|
||||
for (let i = 0; i < todoContentElements.length; i++) {
|
||||
if (todoContentElements[i] === document.activeElement || todoContentElements[i].contains(document.activeElement)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 监听虚拟键盘状态变化
|
||||
watch(isKeyboardVisible, (newVal) => {
|
||||
updateToolbarVisibility()
|
||||
})
|
||||
|
||||
// 初始化编辑器内容
|
||||
onMounted(() => {
|
||||
if (editorRef.value) {
|
||||
@@ -727,11 +812,14 @@ onMounted(() => {
|
||||
|
||||
// 显示工具栏
|
||||
const showToolbar = () => {
|
||||
// 只有当虚拟键盘可见时才显示工具栏
|
||||
if (isKeyboardVisible.value) {
|
||||
isToolbarVisible.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏工具栏
|
||||
const hideToolbar = () => {
|
||||
// 处理编辑器失焦
|
||||
const handleBlur = () => {
|
||||
// 不立即隐藏工具栏,而是通过handleToolbarFocusOut处理
|
||||
// 添加延迟以确保点击工具栏按钮时不会立即隐藏
|
||||
setTimeout(() => {
|
||||
@@ -764,6 +852,11 @@ const handleToolClick = (action, event) => {
|
||||
// 对于待办事项,确保工具栏保持可见
|
||||
isToolbarVisible.value = true
|
||||
}
|
||||
|
||||
// 确保工具栏在虚拟键盘可见时保持显示
|
||||
if (isKeyboardVisible.value) {
|
||||
isToolbarVisible.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// 保持工具栏可见
|
||||
@@ -791,8 +884,8 @@ const handleToolbarFocusOut = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 只有在没有待办事项获得焦点时才隐藏工具栏
|
||||
if (!todoHasFocus) {
|
||||
// 只有在没有待办事项获得焦点且虚拟键盘不可见时才隐藏工具栏
|
||||
if (!todoHasFocus && !isKeyboardVisible.value) {
|
||||
isToolbarVisible.value = false
|
||||
}
|
||||
}
|
||||
@@ -925,6 +1018,20 @@ defineExpose({
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* 当虚拟键盘可见时,调整工具栏位置 */
|
||||
.toolbar.keyboard-visible {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* 使用visualViewport API动态调整工具栏位置 */
|
||||
.toolbar.dynamic-position {
|
||||
bottom: calc(100vh - var(--viewport-height, 100vh));
|
||||
}
|
||||
|
||||
.toolbar.visible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
padding: 0.375rem;
|
||||
margin-right: 0.375rem;
|
||||
@@ -1097,6 +1204,7 @@ defineExpose({
|
||||
border: 0.625rem solid white;
|
||||
border-radius: 0.2rem;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.18);
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
/* 待办事项样式 */
|
||||
|
||||
Reference in New Issue
Block a user