Vue.js 显示弹出框工具函数

点击一块区域或者聚焦输入框,让弹窗根据要弹出元素的宽高和鼠标距离屏幕所剩的距离自动弹出到此元素的上下左右,或者固定弹出上下左右。实现方法是 position 为 fixed。

2649 热度
883 浏览

根据当前点击位置,显示弹窗。内部会判断在距离浏览器窗口上下左右的最佳显示位置。

只做定位作用,要把弹窗 dom 显示出来再调用此方法。

javascript 复制代码
/**
 * 根据点击位置智能定位弹窗
 * @param {Vue} THIS - 当前 Vue 实例
 * @param {HTMLElement} clickElement - 点击的元素
 * @param {HTMLElement} popupElement - 弹窗元素(已显示)
 * @param {string} type - 弹出方位,可选:top / bottom / left / right / top-left / top-right / bottom-left / bottom-right
 */
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;

        let top = 0, left = 0;
        popupElement.style.position = 'fixed';

        // --- 基础位置计算 ---
        const centerX = clickRect.left + clickRect.width / 2;
        const centerY = clickRect.top + clickRect.height / 2;

        const preferred = type || 'auto';

        // --- 判断上下方向 ---
        const spaceTop = clickRect.top;
        const spaceBottom = screenHeight - clickRect.bottom;
        const spaceLeft = clickRect.left;
        const spaceRight = screenWidth - clickRect.right;

        // --- 自动方向选择(当 type 未指定) ---
        let finalType = preferred;
        if (preferred === 'auto') {
            if (spaceBottom >= popupHeight) finalType = 'bottom';
            else if (spaceTop >= popupHeight) finalType = 'top';
            else if (spaceRight >= popupWidth) finalType = 'right';
            else if (spaceLeft >= popupWidth) finalType = 'left';
            else finalType = 'bottom'; // 默认下方
        }

        // --- 根据方位设置坐标 ---
        switch (finalType) {
            case 'top':
                top = clickRect.top - popupHeight;
                left = centerX - popupWidth / 2;
                break;
            case 'bottom':
                top = clickRect.bottom;
                left = centerX - popupWidth / 2;
                break;
            case 'left':
                top = centerY - popupHeight / 2;
                left = clickRect.left - popupWidth;
                break;
            case 'right':
                top = centerY - popupHeight / 2;
                left = clickRect.right;
                break;
            case 'top-left':
                top = clickRect.top - popupHeight;
                left = clickRect.left;
                break;
            case 'top-right':
                top = clickRect.top - popupHeight;
                left = clickRect.right - popupWidth;
                break;
            case 'bottom-left':
                top = clickRect.bottom;
                left = clickRect.left;
                break;
            case 'bottom-right':
                top = clickRect.bottom;
                left = clickRect.right - popupWidth;
                break;
        }

        // --- 防止出界处理 ---
        if (left + popupWidth > screenWidth - 5) left = screenWidth - popupWidth - 5;
        if (left < 5) left = 5;
        if (top + popupHeight > screenHeight - 5) top = screenHeight - popupHeight - 5;
        if (top < 5) top = 5;

        // --- 应用位置 ---
        popupElement.style.top = `${top}px`;
        popupElement.style.left = `${left}px`;
    });
}
Vue.js 显示弹出框工具函数

声明:Web前端小站 - 前端博客 - 王搏的个人博客|版权所有,违者必究|如未注明,均为原创

转载:转载请注明原文链接 - Vue.js 显示弹出框工具函数

评论 (0)

0/50
暂无评论,快来抢沙发吧~