fix: 标签栏滚轮滚动和自动定位问题
- 修复滚轮不生效:使用 capture 阶段监听 wheel 事件 - 修复滚轮不生效:添加 stopPropagation 防止事件被拦截 - 新增自动滚动到活动标签:切换/打开标签时自动定位到可见区域 - 优化 CSS:移除 #tab-bar 的 overflow,由 #tab-list 统一负责滚动 - 添加平滑滚动:scroll-behavior: smooth
This commit is contained in:
@@ -30,17 +30,35 @@ export function TabBar() {
|
|||||||
|
|
||||||
const handleWheel = (e: WheelEvent) => {
|
const handleWheel = (e: WheelEvent) => {
|
||||||
// 只有当标签列表有水平滚动空间时才处理
|
// 只有当标签列表有水平滚动空间时才处理
|
||||||
if (tabList.scrollWidth <= tabList.clientWidth) return
|
const hasHorizontalScroll = tabList.scrollWidth > tabList.clientWidth
|
||||||
|
if (!hasHorizontalScroll) return
|
||||||
|
|
||||||
|
// 阻止默认的垂直滚动
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
// 将垂直滚动转换为水平滚动
|
// 将垂直滚动转换为水平滚动
|
||||||
tabList.scrollLeft += e.deltaY
|
tabList.scrollLeft += e.deltaY
|
||||||
}
|
}
|
||||||
|
|
||||||
tabList.addEventListener('wheel', handleWheel, { passive: false })
|
// 使用 capture 阶段,确保事件能被捕获
|
||||||
return () => tabList.removeEventListener('wheel', handleWheel)
|
tabList.addEventListener('wheel', handleWheel, { passive: false, capture: true })
|
||||||
|
return () => tabList.removeEventListener('wheel', handleWheel, { capture: true })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// 自动滚动到活动标签
|
||||||
|
useEffect(() => {
|
||||||
|
if (!tabListRef.current || !activeTabId) return
|
||||||
|
|
||||||
|
// 使用 requestAnimationFrame 确保 DOM 已更新
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const activeTab = tabListRef.current?.querySelector('.tab-item.active')
|
||||||
|
if (activeTab) {
|
||||||
|
activeTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [activeTabId])
|
||||||
|
|
||||||
const handleClose = useCallback((e: React.MouseEvent, tabId: string) => {
|
const handleClose = useCallback((e: React.MouseEvent, tabId: string) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
const tab = tabs.find(t => t.id === tabId)
|
const tab = tabs.find(t => t.id === tabId)
|
||||||
|
|||||||
@@ -470,26 +470,7 @@ html, body {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
overflow-x: auto;
|
/* 不设置 overflow,由 #tab-list 负责滚动 */
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 标签栏滚动条:默认隐藏,hover 时显示 */
|
|
||||||
#tab-bar::-webkit-scrollbar {
|
|
||||||
height: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tab-bar::-webkit-scrollbar-thumb {
|
|
||||||
background: var(--border);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#tab-bar::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: var(--text-tertiary);
|
|
||||||
}
|
|
||||||
|
|
||||||
#tab-bar::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tab-list {
|
#tab-list {
|
||||||
@@ -500,9 +481,11 @@ html, body {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
/* 平滑滚动 */
|
||||||
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 标签列表滚动条:默认隐藏,hover 时显示 */
|
/* 标签列表滚动条 */
|
||||||
#tab-list::-webkit-scrollbar {
|
#tab-list::-webkit-scrollbar {
|
||||||
height: 3px;
|
height: 3px;
|
||||||
}
|
}
|
||||||
@@ -520,6 +503,14 @@ html, body {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tab-list::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--text-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tab-list::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user