fix: 编辑器拖拽修复 — 扩大拖拽区域+退出最大化+边界限制

问题:
- 标签栏整体被排除导致可拖拽区域几乎为零
- 最大化/全屏后拖拽不工作
- 没有拖拽视觉提示

修复:
- 添加⠿拖拽把手图标(cursor-grab)
- 只排除button/input/select, 标签栏空白处可拖拽
- 拖拽时自动退出最大化/全屏模式
- 边界限制(不拖出屏幕)
- 拖拽结束触发Monaco重新layout
This commit is contained in:
Your Name
2026-05-31 02:31:56 +08:00
parent cba8b3d8f6
commit c570801119
+22 -8
View File
@@ -62,10 +62,12 @@
<!-- Floating Editor Panel (draggable + resizable + file tree) -->
<div id="editorPanel" class="hidden fixed z-40 flex flex-col" style="right:24px;bottom:60px;width:75vw;height:65vh;min-width:500px;min-height:300px;border-radius:12px;overflow:hidden;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5);border:1px solid rgb(51 65 85);background:rgb(15 23 42)">
<!-- Drag handle + tabs + buttons -->
<div id="editorHeader" class="flex items-center bg-slate-900 border-b border-slate-800 shrink-0 cursor-move select-none">
<div id="editorHeader" class="flex items-center bg-slate-900 border-b border-slate-800 shrink-0 select-none">
<!-- Drag grip icon -->
<div class="px-1.5 py-2 text-slate-600 cursor-grab active:cursor-grabbing shrink-0" title="拖拽移动"></div>
<!-- File tree toggle -->
<button onclick="toggleEditorTree()" id="treeToggleBtn" class="text-slate-500 hover:text-white px-2.5 py-2 text-sm hover:bg-slate-700 shrink-0" title="文件树">🌳</button>
<!-- Tabs -->
<!-- Tabs (clickable, not draggable) -->
<div id="editorTabBar" class="flex flex-1 overflow-x-auto min-w-0"></div>
<!-- Right buttons -->
<div class="flex items-center shrink-0">
@@ -826,22 +828,34 @@
const header=document.getElementById('editorHeader');
const panel=document.getElementById('editorPanel');
let dragging=false,startX,startY,startLeft,startTop;
header.addEventListener('mousedown',e=>{
if(e.target.closest('button')||e.target.closest('#editorTabBar'))return;
function startDrag(e){
// Only block drag on interactive elements (buttons, inputs, specific tab clicks)
if(e.target.closest('button')||e.target.closest('input')||e.target.closest('select'))return;
// Allow drag from: grip icon, empty header space, tab bar background
dragging=true;
_editorMaximized=false;_editorFullscreen=false; // Exit maximize/fullscreen on drag
const rect=panel.getBoundingClientRect();
startX=e.clientX;startY=e.clientY;
startLeft=rect.left;startTop=rect.top;
panel.style.right='auto';panel.style.bottom='auto';
panel.style.width=rect.width+'px';panel.style.height=rect.height+'px';
panel.style.left=startLeft+'px';panel.style.top=startTop+'px';
panel.style.borderRadius='12px';
document.body.style.userSelect='none';
});
e.preventDefault();
}
header.addEventListener('mousedown',startDrag);
document.addEventListener('mousemove',e=>{
if(!dragging)return;
panel.style.left=(startLeft+e.clientX-startX)+'px';
panel.style.top=(startTop+e.clientY-startY)+'px';
const x=Math.max(0,Math.min(window.innerWidth-100,startLeft+e.clientX-startX));
const y=Math.max(0,Math.min(window.innerHeight-50,startTop+e.clientY-startY));
panel.style.left=x+'px';panel.style.top=y+'px';
});
document.addEventListener('mouseup',()=>{
if(dragging){dragging=false;document.body.style.userSelect='';
if(_activeTab>=0&&_openTabs[_activeTab].editor)_openTabs[_activeTab].editor.layout();
}
});
document.addEventListener('mouseup',()=>{dragging=false;document.body.style.userSelect=''});
})();
// ── Resize ──