对话框样式弹出提示框js插件- PopoverTip

9 篇文章 1 订阅
4 篇文章 0 订阅
/**
 *  对话框式弹出提示框插件 - PopoverTip
 *  使用方法:
 *    1. 引入该js文件
 *    2. 在需要使用弹出框的元素上添加 class "popover-trigger",
 *       并设置 data-placement 属性指定弹出方向(可选,默认为 auto)
 *    3. 在触发元素后面添加弹出框内容,并包裹在 class 为 "popover-tip" 的元素中
 *  例如:
 *    <div class="popover-wrapper">
 *        <button class="popover-trigger" data-placement="right">触发弹出框</button>
 *        <div class="popover-tip">
 *            <p>弹出框内容</p>
 *        </div>
 *    </div>
 */
(function() {
    // 创建样式表并添加到文档头部
    const style = document.createElement('style');
    style.innerHTML = `
        .popover-wrapper {
            position: relative;
            display: inline-block;
        }

        .popover-tip {
            display: none;
            position: absolute;
            visibility: hidden; /* 隐藏,但会渲染 */
            background-color: #fff;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 10px;
            z-index: 10;
            width: fit-content;
        }

        .popover-tip.show {
            display: block;
            visibility: visible;
        }

        .popover-tip::before {
            content: '';
            position: absolute;
            border: 6px solid transparent;
            z-index: -1;
        }

        /* 箭头样式 */
        .popover-tip.top::before {
            border-top-color: inherit;
            left: 50%;
            top: 100%;
            transform: translateX(-50%);
        }

        .popover-tip.bottom::before {
            border-bottom-color: inherit;
            left: 50%;
            bottom: 100%;
            transform: translateX(-50%);
        }

        .popover-tip.left::before {
            border-left-color: inherit;
            top: 50%;
            left: 100%;
            transform: translateY(-50%);
        }

        .popover-tip.right::before {
            border-right-color: inherit;
            top: 50%;
            right: 100%;
            transform: translateY(-50%);
        }
    `;
    document.head.appendChild(style);
    // 初始化弹出框
    function initPopoverTip() {
        const triggers = document.querySelectorAll('.popover-trigger');
        triggers.forEach(trigger => {
            trigger.addEventListener('click', function(event) {
                const popover = this.nextElementSibling || this.parentElement.querySelector('.popover-tip');
                let placement = this.dataset.placement || 'top';

                // 计算弹出框位置
                const triggerRect = this.getBoundingClientRect();
                const windowHeight = window.innerHeight;
                const windowWidth = window.innerWidth;

                // 先将弹出框显示出来,以便获取其尺寸
                popover.style.display = 'block';
                const popoverRect = popover.getBoundingClientRect();

                let top = 0;
                let left = 0;

                if (placement === 'auto') {
                    // 自动调整位置逻辑
                    const spaceAbove = triggerRect.top;
                    const spaceBelow = windowHeight - triggerRect.bottom;
                    const spaceLeft = triggerRect.left;
                    const spaceRight = windowWidth - triggerRect.right;

                    if (spaceAbove >= popoverRect.height && spaceAbove >= spaceBelow) {
                        placement = 'top';
                        top -= popoverRect.height + 8; // 8px 箭头偏移
                        // 水平居中
                        left += (triggerRect.width - popoverRect.width) / 2;
                    } else if (spaceBelow >= popoverRect.height) {
                        placement = 'bottom';
                        top += triggerRect.height + 8;
                        // 水平居中
                        left += (triggerRect.width - popoverRect.width) / 2;
                    } else if (spaceLeft >= popoverRect.width && spaceLeft >= spaceRight) {
                        placement = 'left';
                        left -= popoverRect.width + 8;
                        // 垂直居中
                        top += (triggerRect.height - popoverRect.height) / 2;
                    } else if (spaceRight >= popoverRect.width) {
                        placement = 'right';
                        left += triggerRect.width + 8;
                        // 垂直居中
                        top += (triggerRect.height - popoverRect.height) / 2;
                    } else {
                        // 如果空间不足,默认顶部弹出
                        placement = 'top';
                        top -= popoverRect.height + 8; // 8px 箭头偏移
                        // 水平居中
                        left += (triggerRect.width - popoverRect.width) / 2;
                    }
                } else {
                    // 非自动模式下,根据选择的位置调整
                    switch (placement) {
                        case 'top':
                            top -= popoverRect.height + 8;
                            // 水平居中
                            left += (triggerRect.width - popoverRect.width) / 2;
                            break;
                        case 'bottom':
                            top += triggerRect.height + 8;
                            // 水平居中
                            left += (triggerRect.width - popoverRect.width) / 2;
                            break;
                        case 'left':
                            left -= popoverRect.width + 8;
                            // 垂直居中
                            top += (triggerRect.height - popoverRect.height) / 2;
                            break;
                        case 'right':
                            left += triggerRect.width + 8;
                            // 垂直居中
                            top += (triggerRect.height - popoverRect.height) / 2;
                            break;
                    }
                }
                popover.style.top = `${top}px`;
                popover.style.left = `${left}px`;
                popover.classList.add('show', placement);
                // 点击其他区域关闭弹出框
                document.addEventListener('click', function closePopover(event) {
                    if (!trigger.contains(event.target) && !popover.contains(event.target)) {
                        popover.classList.remove('show', 'top', 'bottom', 'left', 'right');
                        document.removeEventListener('click', closePopover);
                    }
                });
                event.stopPropagation();
            });
        });
    }
    // 页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initPopoverTip);
    } else {
        initPopoverTip();
    }
}());

使用方法:

  • 将以上代码保存为 .js 文件,例如 popover-tip.js
  • 在 HTML 文件中引入该文件:
<script src="popover-tip.js"></script>
  • 按照以下结构添加触发元素和弹出框内容:
<div class="popover-wrapper">
    <!-- 这里不限于是button等按钮元素,可以任何元素,只要有class="popover-trigger"和data-placement="top"即可 -->
    <button class="popover-trigger" data-placement="right">触发弹出框</button>
    <div class="popover-tip">
        <p>弹出框内容</p>
    </div>
</div>

​​​参数说明:

  • data-placement:可选参数,指定弹出框的方向,支持 topbottomleftright 和 auto(自动判断),默认为 auto

注意:

  • 确保弹出框元素(.popover-tip)紧跟在触发元素后面。
  • 可以根据需要自定义弹出框的样式和内容。

现在,您只需引入该 JavaScript 文件,并按照上述步骤添加 HTML 结构,即可轻松实现一个功能完善的弹出提示框组件。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值