点击一块区域或者聚焦输入框,让弹窗根据要弹出元素的宽高和鼠标距离屏幕所剩的距离自动弹出到此元素的上下左右,或者固定弹出上下左右。实现方法是 position 为 fixed。
根据当前点击位置,显示弹窗。内部会判断在距离浏览器窗口上下左右的最佳显示位置。
只做定位作用,要把弹窗 dom 显示出来再调用此方法。
/**
* @param {*} THIS // 当前 vue 实例
* @param {*} clickElement // 点击的 dom
* @param {*} popupElement // 弹窗的 dom
* @param {*} type // 弹出的位置 top bottom left right top-right top-left bottom-right bottom-left
*/
export function popup(THIS, clickElement, popupElement, type) {
// 显示弹出框
THIS.$nextTick(_ => {
// 屏幕宽
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
// 获取点击元素的位置信息
const clickRect = clickElement.getBoundingClientRect();
// 计算弹出框的位置
const popupWidth = popupElement.offsetWidth;
const popupHeight = popupElement.offsetHeight;
const popupTop = clickRect.bottom;
let popupLeft = clickRect.left - (popupWidth / 2) + clickRect.width / 2;
const defaultLeft = 10; // 默认距离
// 判断是否需要将弹出框显示在上方
const popupBottom = popupTop + popupHeight;
const isOverflowBottom = popupBottom > screenHeight;
const isOverflowTop = popupTop - popupHeight < 0;
popupElement.style.position = 'fixed';
if (type == 'top' || type == 'top-left' || type == 'top-right') {
popupElement.style.top = `${clickRect.top - popupHeight}px`;
} else if (type == 'bottom' || type == 'bottom-left' || type == 'bottom-right') {
popupElement.style.top = `${popupTop}px`;
} else if (isOverflowBottom && !isOverflowTop) {
popupElement.style.top = `${clickRect.top - popupHeight}px`;
} else {
popupElement.style.top = `${popupTop}px`;
}
// 判断是否需要将弹出框显示在右方
if (type == 'left' || type == 'top-left' || type == 'bottom-left') {
popupElement.style.left = `${clickRect.left}px`;
} else if (type == 'right' || type == 'top-right' || type == 'bottom-right') {
popupElement.style.left = `${clickRect.left - popupWidth - clickRect.width}px`;
} else if (popupLeft + popupWidth >= screenWidth) { // 右边超出