html - 气泡弹窗 popover 的实现

需求:点击按钮的时候,下方弹出气泡窗口,按钮移动的时候,按钮跟随移动,按钮隐藏的时候,气泡跟着隐藏。

使用布局实现

通过 CSS 样式实现的吸附窗口,开发第一优选;

优点:性能最好,可以通过 style 微调属性;

缺点:多嵌套了一层 div,可能会影响布局。

比如:button-group 会失效,这个影响挺大的。

.sea-float-box {
  position: relative;
  display: inline-block;

  .float-top {
    @include float-panel;
    left: 0; // 左对齐
    //right: 0; // 右对齐
    bottom: 100%; // 底边对齐
    margin-bottom: 10px;
  }

  .float-bottom {
    @include float-panel;
    left: 0; // 左对齐
    //right: 0; // 右对齐
    top: 100%; // 顶部对齐
    margin-top: 10px;
  }
}

使用差值定位

简单说,就是在父级容器中,增加一个定位组件(div),

计算按钮与定位组件之间的相对位置,之后再推导出弹窗所在的位置。

优点:

  • 包含一定计算量,但是计算不复杂;
  • 兼容性强,只要保证 “按钮、弹窗和定位组件” 三者相对位置不变,界面怎么拖动都不受影响;

缺点:

  • 会增加一个隐藏 div,特殊场合下,仍然会影响布局。
.sea-anchor-point {
  position: relative;
  width: 100%; // 用于宽度对齐 
  height: 0;
}

JS 伪代码

// 创建气泡窗口
const div = document.createElement('div');

// 计算按钮与定位组件之间的差值
const left = ref_rect.left - anchor_rect.left
const top = ref_rect.top - anchor_rect.top

// 设置气泡窗口的绝对位置,并追加到定位组件中
div.style.top = top + 'px';
div.style.left = left + 'px';
anchorRef.value.appendChild(div);

纯计算实现

不推荐花时间做,因为有太多需要考虑的场景:

  • 事件冲突,需要区分 window、按钮、气泡 3 个 click 事件;
  • 浏览器缩放、组件发生滚动,事件很难捕获;
  • 特殊的拖拽事件:快速拖拽的时候,松开按钮时,会继续向前移动一小段距离,这种情况,气泡跟随效果极难实现(openlayer 开发中遇到)。

posted on 2025-08-05 16:44  疯狂的妞妞  阅读(68)  评论(0)    收藏  举报

导航