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

基于JavaScript API的场景化Web Scene开发:多场景创建报错求助

核心报错原因
  • 未提前获取DOM实例:代码直接使用buttonA、buttonB绑定点击事件,但没有通过DOM API获取对应按钮元素,会直接抛出未定义引用错误,这是切换第二个场景报错的核心诱因。
  • 场景逻辑缺失:当前仅实现了图层可见性切换,没有绑定你需要的分时段光照、时间参数,无法实现不同时段太阳运动影响的展示需求。
  • 无空值校验:图层加载完成前点击按钮,scenarioA/scenarioB为null时调用visible属性会触发报错。
解决实现方案

不需要重复创建WebScene实例,复用现有视图仅切换配置即可,优化后的核心逻辑如下:

  1. 先获取按钮DOM实例再绑定事件
  2. 预先定义每个场景对应的时间、光照等配置参数
  3. 切换场景时同步更新图层可见性、时间、光照参数
  4. 所有操作前增加非空校验,避免空值报错
完整可运行代码
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21/"></script>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #selection {
        position: absolute;
        bottom: 20px;
        left: 20px;
        right: 20px;
        display: flex;
        justify-content: center;
      }

      .esri-button {
        max-width: 300px;
        margin-left: 5px;
      }

      .esri-button--secondary {
        background-color: white;
      }
    </style>

    <script>
      require([
        "esri/WebScene",
        "esri/views/SceneView",
        "esri/widgets/ShadowCast"
      ], function (WebScene, SceneView, ShadowCast) {
        // 提前获取DOM元素
        const buttonA = document.getElementById('scenarioA')
        const buttonB = document.getElementById('scenarioB')

        const view = new SceneView({
          container: "viewDiv",
          map: new WebScene({
            portalItem: {
              id: "f2220db76c6448b4be8083d19ef4cf8d"
            }
          }),
          qualityProfile: "high",
          environment: {
            lighting: {
              directShadowsEnabled: true
            }
          }
        });

        const widget = new ShadowCast({ view });
        view.ui.add(widget, "top-right");

        // 预定义不同场景的配置:时间、阴影开关等,可按需扩展
        const scenarioConfig = {
          A: {
            time: new Date("May 1, 2021 09:00:00"),
            shadowEnabled: true
          },
          B: {
            time: new Date("May 1, 2021 15:00:00"),
            shadowEnabled: true
          }
        }

        let scenarioA = null;
        let scenarioB = null;

        view.when(() => {
          view.map.allLayers.forEach((layer) => {
            if (layer.title === "Development Scenario A") {
              scenarioA = layer;
            }
            if (layer.title === "Development Scenario B") {
              scenarioB = layer;
            }
          });
          // 初始化默认显示场景A
          toggleScenarios("A")
        });

        buttonA.addEventListener("click", (event) => {
          toggleScenarios("A");
        });

        buttonB.addEventListener("click", (event) => {
          toggleScenarios("B");
        });

        function toggleScenarios(active) {
          // 非空校验,避免图层未加载完成时报错
          if(!scenarioA || !scenarioB) return
          
          // 切换图层可见性
          scenarioA.visible = active === "A";
          scenarioB.visible = active === "B";

          // 切换场景对应的时间和光照配置
          widget.viewModel.date = scenarioConfig[active].time;
          view.environment.lighting.directShadowsEnabled = scenarioConfig[active].shadowEnabled;

          // 切换按钮样式
          if (active === "B") {
            buttonA.classList.add("esri-button--secondary");
            buttonB.classList.remove("esri-button--secondary");
          } else {
            buttonA.classList.remove("esri-button--secondary");
            buttonB.classList.add("esri-button--secondary");
          }
        }
      });
    </script>
  </head>

  <body>
    <div id="viewDiv">
      <div id="selection">
        <button id="scenarioA" class="esri-button">Scenario A</button>
        <button id="scenarioB" class="esri-button esri-button--secondary">
          Scenario B
        </button>
      </div>
    </div>
  </body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:45:05