Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export default class RightMenu {
this.addEvent(window, 'resize', this.destroyMenu.bind(this))
// 页面点击时销毁菜单栏
this.addEvent(document, 'mousedown', (e) => {
const hasMenu = e['path']?.some((node: HTMLDivElement) => node === menu)
const hasMenu = (e['path'] || e.composedPath())?.some((node: HTMLDivElement) => node === menu)
if (!hasMenu) this.destroyMenu()
})
}
Expand Down Expand Up @@ -278,13 +278,24 @@ export default class RightMenu {
// 添加二级菜单
if (opt.children && opt.children.length) {
const ul = this.renderMenu(opt.children)
const parentMouseLeaveListener = () => li.removeChild(ul)
li.addEventListener('mouseenter', (e) => {
li.appendChild(ul)
li.parentElement?.removeEventListener('mouseleave', parentMouseLeaveListener)
layoutMenuPositionEffect(li, ul)
})
li.addEventListener('mouseleave', (e: MouseEvent) => {
if (!e['toElement']) return
let curr = e['toElement']

if (li.parentElement && curr === li.parentElement && (e.offsetX < 0 || e.offsetX >= li.offsetWidth)) {
// fix 存在滚动条时,从左右两侧移入子菜单
li.parentElement.addEventListener('mouseleave', parentMouseLeaveListener, {
once: true,
})
return
}

while (curr) {
// 如果路径里存在 ul 标签, 就不需要销毁
if (curr === ul) return
Expand Down
19 changes: 17 additions & 2 deletions packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,24 @@ export const layoutMenuPositionEffect = (

const layoutToTop = () => {
let y = baseY
// 尝试向上布局,判断菜单最顶端是否超出屏幕上边缘(视窗高度)
// 尝试向上布局,判断菜单最底端是否超出屏幕下边缘(视窗高度)
if (menu.offsetHeight + y > window.innerHeight) {
y = baseY + baseH - height
const topY = baseY + baseH - height
if (topY >= 0) {
// 可以向上布局
y = topY
return y
}
// 上下都放不下时,使用向上、向下两种方式中更高的区域+滚动条的形式
const bottomHeight = window.innerHeight - baseY
const topHeight = baseY + baseH
const isBottom = bottomHeight > topHeight
const menuHeight = Math.max(bottomHeight, topHeight)
const menuMaxHeight = Math.floor(menuHeight - 5)
y = isBottom ? baseY : baseY + baseH - menuMaxHeight
menu.style.maxHeight = `${menuMaxHeight}px`
menu.style.overflowY = 'auto'
return y
}
return y
}
Expand Down