fix: 修复右键菜单超出屏幕边界问题

在以下组件中添加了防止右键菜单超出屏幕边界的防护措施:
- WorkspaceConnectionList.vue
- QuickCommandsView.vue
- CommandHistoryView.vue
This commit is contained in:
Baobhan Sith
2025-05-11 23:31:03 +08:00
parent ccfb93d019
commit 564db89d0f
3 changed files with 162 additions and 33 deletions
@@ -334,6 +334,39 @@ const showContextMenu = (event: MouseEvent, connection: ConnectionInfo) => {
contextMenuVisible.value = true; contextMenuVisible.value = true;
// 添加全局点击监听器以关闭菜单 // 添加全局点击监听器以关闭菜单
document.addEventListener('click', closeContextMenu, { once: true }); document.addEventListener('click', closeContextMenu, { once: true });
// 使用 nextTick 获取菜单尺寸并调整位置以防止超出屏幕
nextTick(() => {
const menuElement = document.querySelector('.context-menu') as HTMLElement;
if (menuElement) {
const menuRect = menuElement.getBoundingClientRect();
let finalX = contextMenuPosition.value.x;
let finalY = contextMenuPosition.value.y;
const menuWidth = menuRect.width;
const menuHeight = menuRect.height;
// 调整水平位置
if (finalX + menuWidth > window.innerWidth) {
finalX = window.innerWidth - menuWidth - 5;
}
// 调整垂直位置
if (finalY + menuHeight > window.innerHeight) {
finalY = window.innerHeight - menuHeight - 5;
}
// 确保菜单不超出屏幕左上角
finalX = Math.max(5, finalX);
finalY = Math.max(5, finalY);
// 更新位置
if (finalX !== contextMenuPosition.value.x || finalY !== contextMenuPosition.value.y) {
console.log(`[WkspConnList] Adjusting context menu position: (${contextMenuPosition.value.x}, ${contextMenuPosition.value.y}) -> (${finalX}, ${finalY})`);
contextMenuPosition.value = { x: finalX, y: finalY };
}
}
});
return false; // 彻底停止事件处理 return false; // 彻底停止事件处理
}; };
@@ -400,6 +433,38 @@ const showTagContextMenu = (event: MouseEvent, groupData: (typeof filteredAndGro
tagContextMenuVisible.value = true; tagContextMenuVisible.value = true;
// 添加全局点击监听器以关闭菜单 // 添加全局点击监听器以关闭菜单
document.addEventListener('click', closeTagContextMenu, { once: true }); document.addEventListener('click', closeTagContextMenu, { once: true });
// 使用 nextTick 获取菜单尺寸并调整位置以防止超出屏幕
nextTick(() => {
const menuElement = document.querySelector('.tag-context-menu') as HTMLElement;
if (menuElement) {
const menuRect = menuElement.getBoundingClientRect();
let finalX = tagContextMenuPosition.value.x;
let finalY = tagContextMenuPosition.value.y;
const menuWidth = menuRect.width;
const menuHeight = menuRect.height;
// 调整水平位置
if (finalX + menuWidth > window.innerWidth) {
finalX = window.innerWidth - menuWidth - 5;
}
// 调整垂直位置
if (finalY + menuHeight > window.innerHeight) {
finalY = window.innerHeight - menuHeight - 5;
}
// 确保菜单不超出屏幕左上角
finalX = Math.max(5, finalX);
finalY = Math.max(5, finalY);
// 更新位置
if (finalX !== tagContextMenuPosition.value.x || finalY !== tagContextMenuPosition.value.y) {
console.log(`[WkspConnList] Adjusting tag context menu position: (${tagContextMenuPosition.value.x}, ${tagContextMenuPosition.value.y}) -> (${finalX}, ${finalY})`);
tagContextMenuPosition.value = { x: finalX, y: finalY };
}
}
});
}; };
// 关闭标签右键菜单 // 关闭标签右键菜单
@@ -844,7 +909,7 @@ const cancelEditingTag = () => {
<!-- Context Menu --> <!-- Context Menu -->
<div <div
v-if="contextMenuVisible" v-if="contextMenuVisible"
class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px]" class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px] context-menu"
:style="{ top: `${contextMenuPosition.y}px`, left: `${contextMenuPosition.x}px` }" :style="{ top: `${contextMenuPosition.y}px`, left: `${contextMenuPosition.x}px` }"
@click.stop @click.stop
> >
@@ -871,7 +936,7 @@ const cancelEditingTag = () => {
<!-- 标签右键菜单 --> <!-- 标签右键菜单 -->
<div <div
v-if="tagContextMenuVisible" v-if="tagContextMenuVisible"
class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[200px]" class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[200px] tag-context-menu"
:style="{ top: `${tagContextMenuPosition.y}px`, left: `${tagContextMenuPosition.x}px` }" :style="{ top: `${tagContextMenuPosition.y}px`, left: `${tagContextMenuPosition.x}px` }"
@click.stop @click.stop
> >
@@ -64,7 +64,7 @@
<!-- Context Menu for Command History --> <!-- Context Menu for Command History -->
<div <div
v-if="commandHistoryContextMenuVisible" v-if="commandHistoryContextMenuVisible"
class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px]" class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px] command-history-context-menu"
:style="{ top: `${commandHistoryContextMenuPosition.y}px`, left: `${commandHistoryContextMenuPosition.x}px` }" :style="{ top: `${commandHistoryContextMenuPosition.y}px`, left: `${commandHistoryContextMenuPosition.x}px` }"
@click.stop @click.stop
> >
@@ -254,6 +254,38 @@ const showCommandHistoryContextMenu = (event: MouseEvent, entry: CommandHistoryE
commandHistoryContextMenuPosition.value = { x: event.clientX, y: event.clientY }; commandHistoryContextMenuPosition.value = { x: event.clientX, y: event.clientY };
commandHistoryContextMenuVisible.value = true; commandHistoryContextMenuVisible.value = true;
document.addEventListener('click', closeCommandHistoryContextMenu, { once: true }); document.addEventListener('click', closeCommandHistoryContextMenu, { once: true });
// 使用 nextTick 获取菜单尺寸并调整位置以防止超出屏幕
nextTick(() => {
const menuElement = document.querySelector('.command-history-context-menu') as HTMLElement;
if (menuElement) {
const menuRect = menuElement.getBoundingClientRect();
let finalX = commandHistoryContextMenuPosition.value.x;
let finalY = commandHistoryContextMenuPosition.value.y;
const menuWidth = menuRect.width;
const menuHeight = menuRect.height;
// 调整水平位置
if (finalX + menuWidth > window.innerWidth) {
finalX = window.innerWidth - menuWidth - 5;
}
// 调整垂直位置
if (finalY + menuHeight > window.innerHeight) {
finalY = window.innerHeight - menuHeight - 5;
}
// 确保菜单不超出屏幕左上角
finalX = Math.max(5, finalX);
finalY = Math.max(5, finalY);
// 更新位置
if (finalX !== commandHistoryContextMenuPosition.value.x || finalY !== commandHistoryContextMenuPosition.value.y) {
console.log(`[CommandHistoryView] Adjusting command history context menu position: (${commandHistoryContextMenuPosition.value.x}, ${commandHistoryContextMenuPosition.value.y}) -> (${finalX}, ${finalY})`);
commandHistoryContextMenuPosition.value = { x: finalX, y: finalY };
}
}
});
}; };
const closeCommandHistoryContextMenu = () => { const closeCommandHistoryContextMenu = () => {
@@ -159,7 +159,7 @@
<!-- Context Menu for Quick Commands --> <!-- Context Menu for Quick Commands -->
<div <div
v-if="quickCommandContextMenuVisible" v-if="quickCommandContextMenuVisible"
class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px]" class="fixed bg-background border border-border/50 shadow-xl rounded-lg py-1.5 z-50 min-w-[180px] quick-command-context-menu"
:style="{ top: `${quickCommandContextMenuPosition.y}px`, left: `${quickCommandContextMenuPosition.x}px` }" :style="{ top: `${quickCommandContextMenuPosition.y}px`, left: `${quickCommandContextMenuPosition.x}px` }"
@click.stop @click.stop
> >
@@ -561,6 +561,38 @@ const showQuickCommandContextMenu = (event: MouseEvent, command: QuickCommandFE)
quickCommandContextMenuPosition.value = { x: event.clientX, y: event.clientY }; quickCommandContextMenuPosition.value = { x: event.clientX, y: event.clientY };
quickCommandContextMenuVisible.value = true; quickCommandContextMenuVisible.value = true;
document.addEventListener('click', closeQuickCommandContextMenu, { once: true }); document.addEventListener('click', closeQuickCommandContextMenu, { once: true });
// 使用 nextTick 获取菜单尺寸并调整位置以防止超出屏幕
nextTick(() => {
const menuElement = document.querySelector('.quick-command-context-menu') as HTMLElement;
if (menuElement) {
const menuRect = menuElement.getBoundingClientRect();
let finalX = quickCommandContextMenuPosition.value.x;
let finalY = quickCommandContextMenuPosition.value.y;
const menuWidth = menuRect.width;
const menuHeight = menuRect.height;
// 调整水平位置
if (finalX + menuWidth > window.innerWidth) {
finalX = window.innerWidth - menuWidth - 5;
}
// 调整垂直位置
if (finalY + menuHeight > window.innerHeight) {
finalY = window.innerHeight - menuHeight - 5;
}
// 确保菜单不超出屏幕左上角
finalX = Math.max(5, finalX);
finalY = Math.max(5, finalY);
// 更新位置
if (finalX !== quickCommandContextMenuPosition.value.x || finalY !== quickCommandContextMenuPosition.value.y) {
console.log(`[QuickCmdView] Adjusting quick command context menu position: (${quickCommandContextMenuPosition.value.x}, ${quickCommandContextMenuPosition.value.y}) -> (${finalX}, ${finalY})`);
quickCommandContextMenuPosition.value = { x: finalX, y: finalY };
}
}
});
}; };
const closeQuickCommandContextMenu = () => { const closeQuickCommandContextMenu = () => {