升级Autodesk APS Viewer时遇TypeError:无法读取null的width属性求助
解决Autodesk APS Viewer升级时的"Cannot read properties of null (reading 'width')"错误
问题背景
将旧版Viewer API升级至最新版Autodesk APS Viewer时,调用自定义脚本加载Viewer资源后初始化Viewer,出现空指针错误,已知问题与脚本和DOM容器的加载顺序有关,但无法定位具体解决方法。
错误信息
Viewer3D.js:600 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'width') at Viewer3D.initialize (Viewer3D.js:600:40) at GuiViewer3D.initialize (GuiViewer3D.js:61:61) at Viewer3D.start (Viewer3D.js:378:29) at <anonymous>:663:31
当前加载脚本
private async loadForgeViewerScriptAndStyle(): Promise<void> { return new Promise<void>((reslove,reject) => { const forgeviewerjs = document.createElement('script'); forgeviewerjs.id = 'forgeviewerjs'; forgeviewerjs.src = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.js'; document.body.appendChild(forgeviewerjs); forgeviewerjs.onload = () => { console.info("Viewer scripts loaded"); const link = document.createElement("link"); link.rel = 'stylesheet'; link.href = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/style.css'; link.type = 'text/css'; link.id = "forgeviewercss"; document.body.appendChild(link); console.info("Viewer CSS loaded"); reslove(); }; forgeviewerjs.onerror = (err) => { console.info("Viewer scripts error:"+err ); reject(err); }; }) }
解决方案
这个错误的核心是初始化Viewer时,指定的DOM容器(div)不存在或未完成渲染,Viewer在initialize阶段需要读取容器的width属性,因此会抛出空指针异常。以下是具体解决步骤:
1. 提前在HTML中定义Viewer容器
确保Viewer的DOM容器在页面加载时就已存在,不要动态创建容器后立即初始化Viewer(避免容器未挂载到DOM树)。示例:
<div id="forgeViewer" style="width: 100%; height: 80vh;"></div>
2. 修正脚本加载逻辑,确保CSS加载完成
当前代码中添加CSS后直接resolve Promise,但未监听CSS的加载状态。修改脚本加载方法,等待CSS加载完成后再resolve,避免样式未就绪导致的潜在问题:
private async loadForgeViewerScriptAndStyle(): Promise<void> { return new Promise<void>((resolve, reject) => { const forgeviewerjs = document.createElement('script'); forgeviewerjs.id = 'forgeviewerjs'; forgeviewerjs.src = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.js'; document.body.appendChild(forgeviewerjs); forgeviewerjs.onload = () => { console.info("Viewer scripts loaded"); const link = document.createElement("link"); link.rel = 'stylesheet'; link.href = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/style.css'; link.type = 'text/css'; link.id = "forgeviewercss"; document.body.appendChild(link); // 监听CSS加载完成后再resolve link.onload = () => { console.info("Viewer CSS loaded"); resolve(); }; link.onerror = () => { console.warn("Viewer CSS load failed, continuing initialization"); resolve(); // CSS加载失败不阻塞Viewer初始化 }; }; forgeviewerjs.onerror = (err) => { console.error("Viewer scripts error:", err); reject(err); }; }) }
3. 确保DOM加载完成后再初始化Viewer
在初始化Viewer前,先确认容器元素存在,并等待DOM完全加载:
async function initViewer() { try { await loadForgeViewerScriptAndStyle(); const container = document.getElementById('forgeViewer'); if (!container) { console.error("Viewer container element not found!"); return; } // 初始化Viewer实例 const viewer = new Autodesk.Viewing.GuiViewer3D(container); const startResult = viewer.start(); if (startResult > 0) { console.error("Failed to start Viewer: WebGL is not supported"); return; } // 后续加载模型等逻辑 // ... } catch (err) { console.error("Viewer initialization failed:", err); } } // 等待DOM完全加载后执行初始化 document.addEventListener('DOMContentLoaded', initViewer);
关键注意点
- 初始化Viewer的时机必须晚于容器元素挂载到DOM树的时间,使用
DOMContentLoaded事件可以确保DOM已完全渲染。 - 每次初始化前都要检查容器元素是否存在,避免因DOM结构变动导致的空指针问题。
内容的提问来源于stack exchange,提问作者TD123123123
相关产品推荐
相关产品推荐

