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

Bootstrap折叠组件中NGL 3D Viewer单次点击加载问题求助

解决单次点击加载3D Viewer的问题

问题原因

点击"Show 3D"时,Bootstrap的折叠动画和3D模型加载同时触发,但第一次点击时,折叠区域还未完全展开,viewport_0元素处于不可见状态,NGL无法正确初始化Stage,导致模型加载失败;第二次点击时折叠区域已展开,才能成功加载。

解决方案

通过监听Bootstrap折叠组件的shown.bs.collapse事件(该事件在折叠区域完全展开后触发),再执行3D模型加载逻辑,同时避免重复创建Stage实例。

修改后完整代码

HTML部分

<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/ngl@latest/dist/ngl.min.js"></script>
</head>

<body>
  <div class="row">
    <div class="col" data-toggle="collapse" data-target="#show_0" id="_show_0" data-pdb-path="https://alphafold.ebi.ac.uk/files/AF-P08047-F1-model_v4.pdb">
      <b>Show 3D</b>
    </div>
  </div>

  <div id="show_0" class="collapse">
    <div class="row">
      <div class="col">
        <div id="viewport_0" style="width:100%; height:800px;"></div>
      </div>
    </div>
  </div>

  <script>
    // 存储已初始化的Stage实例,避免重复加载
    const stageInstances = {};

    function showPDB(path, id) {
      if (stageInstances[id]) return;
      
      const stage = new NGL.Stage(id, {backgroundColor:'white'});
      stageInstances[id] = stage;
      
      stage.loadFile(path).then(function (o) {
        o.addRepresentation("cartoon", {color: 'white' });
        o.autoView();
      });
    }

    // 监听折叠区域展开完成事件
    document.addEventListener('shown.bs.collapse', function(e) {
      const collapseId = e.target.id;
      const index = collapseId.replace('show_', '');
      const viewportId = `viewport_${index}`;
      const triggerEl = document.querySelector(`[data-target="#${collapseId}"]`);
      const pdbPath = triggerEl.dataset.pdbPath;
      
      showPDB(pdbPath, viewportId);
    });
  </script>
</body>

</html>

关键修改点

  • 移除了元素上的onclick属性,改用data-pdb-path存储模型路径,更符合语义化
  • 添加stageInstances对象存储已创建的Stage实例,防止重复初始化
  • 监听shown.bs.collapse事件,确保在折叠区域完全展开后再加载3D模型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:01:28