You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取BootstrapDialog弹窗内div的实际宽高

问题根因

获取到undefined是两个问题叠加导致的:

  • 空依赖数组的useEffect执行时机过早:BootstrapDialog组件默认带开启动画,组件首次挂载时弹窗还处于入场动画阶段,内部DOM没有完成最终布局,部分实现甚至会在动画结束后才渲染内容区,此时要么ref还没绑定到真实DOM,要么元素宽高还没计算完成。
  • 兜底值逻辑错误:wrapperRefPopup.current?.getBoundingClientRect?.()||0这行代码,当可选链返回空值时,兜底的是数字类型的0,从数字上解构width、height属性,得到的结果必然是undefined。
可行解决方案

方案1:对齐弹窗渲染时机,延迟获取尺寸

将弹窗的显隐状态加入useEffect依赖,等弹窗完全打开、动画结束后再读取尺寸:

// 你控制弹窗开关的state,变量名和代码里的open属性对应
const [open, setOpen] = useState(false);

useEffect(() => {
  // 弹窗没打开、ref还没绑定DOM时直接返回
  if (!open || !wrapperRefPopup.current) return;

  // 延迟时间和BootstrapDialog默认入场动画时长对齐,一般为300ms
  const calcTimer = setTimeout(() => {
    const { width, height } = wrapperRefPopup.current.getBoundingClientRect();
    
    // 把d3绘图逻辑移到这里执行
    const svg = select(svgRefPopup.current);
    const svgColorCode = select(svgColorCodeRefPopup.current);
    // 后续绘图逻辑...
  }, 300);

  return () => clearTimeout(calcTimer);
}, [open]);

方案2:使用ResizeObserver监听容器尺寸,稳定性更高

这种方式不需要猜测动画时长,不管弹窗何时完成渲染、后续窗口/容器尺寸是否变化,都能拿到准确值:

useEffect(() => {
  if (!open || !wrapperRefPopup.current) return;

  const resizeObserver = new ResizeObserver((entries) => {
    for (const entry of entries) {
      const { width, height } = entry.contentRect;
      // 拿到准确宽高后执行绘图,可加标记位避免重复绘制
      const svg = select(svgRefPopup.current);
      const svgColorCode = select(svgColorCodeRefPopup.current);
      // 后续绘图逻辑...
    }
  });

  resizeObserver.observe(wrapperRefPopup.current);
  // 组件卸载时取消监听
  return () => resizeObserver.disconnect();
}, [open]);
额外注意事项
  • 修正兜底值写法:如果要加可选链兜底,不要兜底数字0,应该兜底带宽高属性的对象,比如const { width, height } = wrapperRefPopup.current?.getBoundingClientRect?.() || { width: 0, height: 0 };,避免解构报错。
  • 如果用的BootstrapDialog默认开启了keepMounted={false}配置,弹窗关闭时内部DOM会被卸载,必须在open为true时再访问ref,否则会拿到null。
  • 绘图前不要给内部svg写死固定宽度,等拿到容器实际宽度后再设置svg的width和viewBox,避免图表拉伸变形。

内容的提问来源于stack exchange,提问作者C Sharper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:12:22