mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-18 23:21:30 +08:00
87 lines
2.3 KiB
JavaScript
87 lines
2.3 KiB
JavaScript
export default {
|
|
data() {
|
|
return {
|
|
overflowContainerScrollTop: 0,
|
|
overflowContainerScrollLeft: 0
|
|
};
|
|
},
|
|
watch: {
|
|
isOpen() {
|
|
if (this.isOpen) {
|
|
this.$emit('open');
|
|
this.$nextTick(() => {
|
|
this.setPosition();
|
|
this.overflowContainerListener();
|
|
});
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
overflowContainerListener() {
|
|
const { field, flyout } = this.$refs;
|
|
|
|
if (!field || !flyout) return;
|
|
|
|
const fieldRect = field.getBoundingClientRect();
|
|
|
|
if (this.overflowContainerScrollTop !== fieldRect.top) {
|
|
this.setPosition();
|
|
}
|
|
|
|
if (this.overflowContainerScrollLeft !== fieldRect.left) {
|
|
this.setPosition();
|
|
}
|
|
|
|
this.overflowContainerScrollLeft = fieldRect.left;
|
|
this.overflowContainerScrollTop = fieldRect.top;
|
|
|
|
setTimeout(() => {
|
|
this.overflowContainerListener();
|
|
}, 10);
|
|
},
|
|
setPosition() {
|
|
const { field, flyout } = this.$refs;
|
|
|
|
if (!field || !flyout) return;
|
|
|
|
const rect = field.getBoundingClientRect();
|
|
const screenHeight = window.innerHeight;
|
|
|
|
const windowHasScroll = document.documentElement.scrollHeight > document.documentElement.clientHeight;
|
|
let rightScrollOffset = 0;
|
|
const { left, width } = rect;
|
|
const top = rect.top + rect.height;
|
|
const bottom = screenHeight - rect.bottom + rect.height;
|
|
const right = window.innerWidth - rect.right;
|
|
if (windowHasScroll) {
|
|
rightScrollOffset = 14;
|
|
}
|
|
|
|
if (this.fixedWidth) {
|
|
flyout.style.width = `${width}px`;
|
|
} else {
|
|
flyout.style.minWidth = `${width}px`;
|
|
}
|
|
|
|
if (this.position === 'right') {
|
|
flyout.style.right = `${right - rightScrollOffset}px`;
|
|
flyout.style.left = 'unset';
|
|
} else {
|
|
flyout.style.left = `${left}px`;
|
|
flyout.style.right = 'unset';
|
|
}
|
|
|
|
if (bottom < top) {
|
|
flyout.style.bottom = `${bottom}px`;
|
|
flyout.style.top = 'unset';
|
|
flyout.style.boxShadow = '0px -16px 32px 0px rgba(16, 24, 40, 0.07)';
|
|
flyout.style.maxHeight = `${screenHeight - bottom - 25}px`;
|
|
} else {
|
|
flyout.style.top = `${top}px`;
|
|
flyout.style.bottom = 'unset';
|
|
flyout.style.boxShadow = '';
|
|
flyout.style.maxHeight = `${screenHeight - top - 25}px`;
|
|
}
|
|
}
|
|
}
|
|
};
|