fix(editor): 右键菜单隐藏逻辑有问题

This commit is contained in:
roymondchen 2022-06-03 22:11:54 +08:00 committed by jia000
parent 6eb1f2418a
commit c99663a3e8

View File

@ -11,13 +11,19 @@
></tool-button>
</div>
<teleport to="body">
<content-menu class="sub-menu" ref="subMenu" :menu-data="subMenuData"></content-menu>
<content-menu
class="sub-menu"
ref="subMenu"
:menu-data="subMenuData"
:is-sub-menu="true"
@hide="hide"
></content-menu>
</teleport>
</div>
</template>
<script lang="ts">
import { defineComponent, nextTick, onMounted, PropType, ref } from 'vue';
import { defineComponent, nextTick, onMounted, onUnmounted, PropType, ref } from 'vue';
import { MenuButton, MenuItem } from '@editor/type';
@ -31,9 +37,16 @@ export default defineComponent({
type: Array as PropType<MenuItem[]>,
default: () => [],
},
isSubMenu: {
type: Boolean,
default: false,
},
},
setup() {
emits: ['hide', 'show'],
setup(props, { emit }) {
const menu = ref<HTMLDivElement>();
const subMenu = ref<any>();
const visible = ref(false);
@ -44,20 +57,35 @@ export default defineComponent({
});
const hide = () => {
if (!visible.value) return;
visible.value = false;
subMenu.value?.hide();
emit('hide');
};
const hideHandler = (e: MouseEvent) => {
const target = e.target as HTMLElement | undefined;
if (!visible.value || !target) {
return;
}
if (menu.value?.contains(target) || subMenu.value?.$el?.contains(target)) {
return;
}
hide();
};
onMounted(() => {
globalThis.addEventListener(
'mouseup',
(e: MouseEvent) => {
if (!visible.value || (e.target && menu.value?.contains(e.target as HTMLElement))) {
return;
}
hide();
},
true,
);
if (props.isSubMenu) return;
globalThis.addEventListener('mousedown', hideHandler, true);
});
onUnmounted(() => {
if (props.isSubMenu) return;
globalThis.removeEventListener('mousedown', hideHandler, true);
});
return {
@ -70,21 +98,26 @@ export default defineComponent({
hide,
show(e: MouseEvent) {
visible.value = true;
// settimeoutmouseupmouseup
setTimeout(() => {
visible.value = true;
nextTick(() => {
const menuHeight = menu.value?.clientHeight || 0;
nextTick(() => {
const menuHeight = menu.value?.clientHeight || 0;
let top = e.clientY;
if (menuHeight + e.clientY > document.body.clientHeight) {
top = document.body.clientHeight - menuHeight;
}
let top = e.clientY;
if (menuHeight + e.clientY > document.body.clientHeight) {
top = document.body.clientHeight - menuHeight;
}
menuStyle.value = {
top: `${top}px`,
left: `${e.clientX + 2}px`,
};
});
menuStyle.value = {
top: `${top}px`,
left: `${e.clientX}px`,
};
emit('show');
});
}, 300);
},
showSubMenu(item: MenuItem) {