feat: 添加 Ctrl/Cmd+F 快捷键功能以聚焦左侧搜索框,优化事件监听逻辑,提升用户体验
This commit is contained in:
parent
d0adc2ba44
commit
4243f0b01a
@ -50,6 +50,8 @@ const container = shallowRef<HTMLDivElement>();
|
|||||||
const editor = shallowRef<EditorService>();
|
const editor = shallowRef<EditorService>();
|
||||||
const storageLocationService = shallowRef<StorageLocationService>();
|
const storageLocationService = shallowRef<StorageLocationService>();
|
||||||
const client = shallowRef<WebSocket>();
|
const client = shallowRef<WebSocket>();
|
||||||
|
// 左侧边栏元素引用(用于 Ctrl/Cmd+F 聚焦搜索框)
|
||||||
|
const leftSiderEl = shallowRef<HTMLElement>();
|
||||||
|
|
||||||
// 依赖注入
|
// 依赖注入
|
||||||
provide(EDITOR_KEY, editor);
|
provide(EDITOR_KEY, editor);
|
||||||
@ -255,6 +257,8 @@ onMounted(async () => {
|
|||||||
// 添加全局点击事件监听器,用于关闭右键菜单
|
// 添加全局点击事件监听器,用于关闭右键菜单
|
||||||
document.addEventListener('click', handleGlobalClick);
|
document.addEventListener('click', handleGlobalClick);
|
||||||
document.addEventListener('keydown', handleGlobalKeydown);
|
document.addEventListener('keydown', handleGlobalKeydown);
|
||||||
|
// 监听 Ctrl/Cmd+F 聚焦左侧搜索框
|
||||||
|
document.addEventListener('keydown', focusFindKeydownHandler);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@ -273,6 +277,7 @@ onUnmounted(() => {
|
|||||||
// 移除全局事件监听器
|
// 移除全局事件监听器
|
||||||
document.removeEventListener('click', handleGlobalClick);
|
document.removeEventListener('click', handleGlobalClick);
|
||||||
document.removeEventListener('keydown', handleGlobalKeydown);
|
document.removeEventListener('keydown', handleGlobalKeydown);
|
||||||
|
document.removeEventListener('keydown', focusFindKeydownHandler);
|
||||||
});
|
});
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@ -399,6 +404,31 @@ const handleGlobalClick = (event: MouseEvent) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 判断事件目标是否在可编辑区域(输入框/文本域/可编辑元素)
|
||||||
|
const isTypingElement = (el: EventTarget | null) => {
|
||||||
|
const node = el as HTMLElement | null;
|
||||||
|
if (!node) return false;
|
||||||
|
const tag = node.tagName?.toLowerCase();
|
||||||
|
return tag === 'input' || tag === 'textarea' || node.isContentEditable === true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ctrl/Cmd + F 快捷键聚焦左侧搜索输入框
|
||||||
|
const focusFindKeydownHandler = (event: KeyboardEvent) => {
|
||||||
|
const isFindKey = event.key === 'f' || event.key === 'F';
|
||||||
|
if ((event.ctrlKey || event.metaKey) && isFindKey && !isTypingElement(event.target)) {
|
||||||
|
const raw: any = leftSiderEl.value as any;
|
||||||
|
const sider: HTMLElement | null = (raw && raw.$el) ? (raw.$el as HTMLElement) : (raw as HTMLElement | null);
|
||||||
|
if (sider) {
|
||||||
|
const input = sider.querySelector('.search input, .search .ant-input') as HTMLInputElement | null;
|
||||||
|
if (input) {
|
||||||
|
event.preventDefault();
|
||||||
|
input.focus();
|
||||||
|
try { input.select?.(); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理全局键盘事件,ESC键关闭右键菜单
|
* 处理全局键盘事件,ESC键关闭右键菜单
|
||||||
* @param event 键盘事件
|
* @param event 键盘事件
|
||||||
@ -425,7 +455,7 @@ const handleGlobalKeydown = (event: KeyboardEvent) => {
|
|||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
|
|
||||||
<a-layout class="p-16">
|
<a-layout class="p-16">
|
||||||
<a-layout-sider :width="320">
|
<a-layout-sider :width="320" ref="leftSiderEl">
|
||||||
<a-tabs type="card">
|
<a-tabs type="card">
|
||||||
<a-tab-pane key="1" :tab="$t('机器人')">
|
<a-tab-pane key="1" :tab="$t('机器人')">
|
||||||
<RobotGroups v-if="editor" :token="EDITOR_KEY" :sid="sid" :current="current?.id" @change="selectRobot" />
|
<RobotGroups v-if="editor" :token="EDITOR_KEY" :sid="sid" :current="current?.id" @change="selectRobot" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
import { computed, onMounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
|
import { computed, onMounted, onUnmounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { getSceneById, importBinTaskExcel, pushSceneById, saveSceneById } from '../apis/scene';
|
import { getSceneById, importBinTaskExcel, pushSceneById, saveSceneById } from '../apis/scene';
|
||||||
@ -71,6 +71,8 @@ watch(
|
|||||||
|
|
||||||
const container = shallowRef<HTMLDivElement>();
|
const container = shallowRef<HTMLDivElement>();
|
||||||
const editor = shallowRef<EditorService>();
|
const editor = shallowRef<EditorService>();
|
||||||
|
// 左侧边栏元素引用(用于 Ctrl/Cmd+F 聚焦搜索框)
|
||||||
|
const leftSiderEl = shallowRef<HTMLElement>();
|
||||||
provide(EDITOR_KEY, editor);
|
provide(EDITOR_KEY, editor);
|
||||||
|
|
||||||
// 自动生成库位对话框相关状态
|
// 自动生成库位对话框相关状态
|
||||||
@ -96,6 +98,40 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 判断事件目标是否在可编辑区域(输入框/文本域/可编辑元素)
|
||||||
|
const isTypingElement = (el: EventTarget | null) => {
|
||||||
|
const node = el as HTMLElement | null;
|
||||||
|
if (!node) return false;
|
||||||
|
const tag = node.tagName?.toLowerCase();
|
||||||
|
return tag === 'input' || tag === 'textarea' || node.isContentEditable === true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ctrl/Cmd + F 快捷键聚焦左侧搜索输入框
|
||||||
|
const focusFindKeydownHandler = (event: KeyboardEvent) => {
|
||||||
|
const isFindKey = event.key === 'f' || event.key === 'F';
|
||||||
|
if ((event.ctrlKey || event.metaKey) && isFindKey && !isTypingElement(event.target)) {
|
||||||
|
const raw: any = leftSiderEl.value as any;
|
||||||
|
const sider: HTMLElement | null = (raw && raw.$el) ? (raw.$el as HTMLElement) : (raw as HTMLElement | null);
|
||||||
|
if (sider) {
|
||||||
|
const input = sider.querySelector('.search input, .search .ant-input') as HTMLInputElement | null;
|
||||||
|
if (input) {
|
||||||
|
event.preventDefault();
|
||||||
|
input.focus();
|
||||||
|
try { input.select?.(); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 监听 Ctrl/Cmd+F 聚焦左侧搜索框
|
||||||
|
document.addEventListener('keydown', focusFindKeydownHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('keydown', focusFindKeydownHandler);
|
||||||
|
});
|
||||||
|
|
||||||
const editable = ref<boolean>(false);
|
const editable = ref<boolean>(false);
|
||||||
watch(editable, (v) => editor.value?.setState(v));
|
watch(editable, (v) => editor.value?.setState(v));
|
||||||
|
|
||||||
@ -240,7 +276,7 @@ const handleAutoCreateStorageCancel = () => {
|
|||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
|
|
||||||
<a-layout class="p-16">
|
<a-layout class="p-16">
|
||||||
<a-layout-sider :width="320">
|
<a-layout-sider :width="320" ref="leftSiderEl">
|
||||||
<a-tabs type="card">
|
<a-tabs type="card">
|
||||||
<a-tab-pane key="1" :tab="$t('机器人')">
|
<a-tab-pane key="1" :tab="$t('机器人')">
|
||||||
<RobotGroups
|
<RobotGroups
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user