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

Angular 11结合Three.js开发出现getBoundingClientRect is not a function报错求助

问题原因

  • 核心错误出在构造images数组的写法有误:document.querySelectorAll('img')返回的是类数组的NodeList对象,你使用{...}对象展开运算符把它转成了普通对象,再套进数组,最终得到的数组第一个元素是键为数字、值为img元素的对象,而非直接存储DOM元素的数组。
  • 后续map遍历的时候拿到的img变量是普通对象,自然没有DOM元素才有的getBoundingClientRect方法,就会抛出对应报错。

修复方案

第一步:修正images数组构造逻辑

把原来的错误写法替换成把NodeList转成元素数组的写法即可:

ngAfterViewInit() {
  // 两种写法二选一,都是把NodeList转成DOM元素数组
  // 写法1:用Array.from
  let images = Array.from(document.querySelectorAll('img'));
  // 写法2:用数组展开运算符
  // let images = [...document.querySelectorAll('img')];
  this.addImages(images);
}

第二步:可选优化(避免图片未加载导致尺寸获取错误)

ngAfterViewInit仅保证Angular的视图DOM渲染完成,不保证页面内的图片资源加载完成,此时获取尺寸可能拿到0或者默认占位尺寸,建议等待所有图片加载完成后再执行尺寸计算逻辑,优化后的代码示例:

async ngAfterViewInit() {
  const images = Array.from(document.querySelectorAll('img'));
  // 等待所有图片加载完成
  await Promise.all(images.map(img => {
    if (img.complete) return Promise.resolve();
    return new Promise(resolve => img.onload = resolve);
  }))
  this.addImages(images);
}

addImages(images) {
  this.imageStore = images.map(img => {
    const bounds = img.getBoundingClientRect();
    console.log(bounds);

    const geometry = new THREE.PlaneBufferGeometry(bounds.width, bounds.height, 1, 1);
    const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
    const mesh = new THREE.Mesh(geometry, material)
    this.scene.add(mesh);

    return {
      img: img,
      mesh: mesh,
      top: bounds.top,
      left: bounds.left,
      width: bounds.width,
      height: bounds.height
    }
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:15:03