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

如何解决p5.js中全局变量locID赋值后外部仍未定义的问题?

问题解决:选择器联动时全局变量初始化访问异常

问题情况

我开发的应用包含两个下拉选择器:

  • 第一个选择器从JSON文件加载地点数据,选中选项时将对应ID存入全局声明的locID变量
  • 第二个选择器从JSON加载工作坊数据,仅展示与locID匹配的内容

遇到的问题:在setup函数中初始化第二个选择器阶段,访问locID结果为undefined;尝试将let改为var后问题仍未解决。

原代码如下:

let locID;
let select;
let select2;

function preload() {
  data = loadJSON(
    "https://raw.githubusercontent.com/mia-mmt2-2223/leesfestival/main/festival.json"
  );
}

function setup() {
  createCanvas(400, 400);
  //LOCATION  SELECTION
  //create select element with as options name from locations from json
  select = createSelect();
  select.position(10, 10);
  select.option("Select a location");
  for (let i = 0; i < data.locations.length; i++) {
    select.option(data.locations[i].name);
  }
  //when a location is selected, save the location id
  select.changed(function () {
    item = select.value();
    for (let i = 0; i < data.locations.length; i++) {
      if (data.locations[i].name == item) {
        locID = data.locations[i].id;
      }
    }
  });

  //WORKSHOP SELECTION
  //create select element with as options name from workshops where location matches locID from json
  select2 = createSelect();
  select2.position(10, 50);
  select2.option("Select a workshop");
  for (let i = 0; i < data.workshops.length; i++) {
    if (data.workshops[i].location == locID) {
      select2.option(data.workshops[i].name);
    }
  }
}

问题原因

setup函数执行时,用户还未对第一个选择器进行操作,locID变量还未被赋值,因此初始化第二个选择器的筛选逻辑会因为locID为undefined而无法匹配到任何工作坊。而且原代码中第二个选择器的选项只在setup中初始化一次,不会随着locID的变化自动更新。

解决方案

把第二个选择器的选项更新逻辑抽成独立函数,每次第一个选择器的值变化时,先更新locID,再重新渲染第二个选择器的选项:

修改后的代码:

let locID;
let select;
let select2;

function preload() {
  data = loadJSON(
    "https://raw.githubusercontent.com/mia-mmt2-2223/leesfestival/main/festival.json"
  );
}

function setup() {
  createCanvas(400, 400);
  // 地点选择器初始化
  select = createSelect();
  select.position(10, 10);
  select.option("Select a location");
  for (let i = 0; i < data.locations.length; i++) {
    select.option(data.locations[i].name);
  }
  // 地点选择变化时的处理
  select.changed(function () {
    const selectedName = select.value();
    // 找到选中地点对应的ID
    for (let i = 0; i < data.locations.length; i++) {
      if (data.locations[i].name === selectedName) {
        locID = data.locations[i].id;
        break; // 找到后直接跳出循环,提升效率
      }
    }
    // 更新工作坊选择器的选项
    updateWorkshopSelect();
  });

  // 工作坊选择器初始化(仅添加默认选项)
  select2 = createSelect();
  select2.position(10, 50);
  select2.option("Select a workshop");
}

// 负责更新工作坊选择器选项的函数
function updateWorkshopSelect() {
  // 清空原有选项(保留默认选项)
  select2.remove(); // 先移除旧的选择器元素
  select2 = createSelect();
  select2.position(10, 50);
  select2.option("Select a workshop");

  // 筛选并添加匹配locID的工作坊选项
  if (locID !== undefined) {
    for (let i = 0; i < data.workshops.length; i++) {
      if (data.workshops[i].location === locID) {
        select2.option(data.workshops[i].name);
      }
    }
  }
}

关键修改点

  1. 新增updateWorkshopSelect函数,负责重新创建工作坊选择器并筛选匹配locID的选项
  2. 在地点选择器的changed事件中,找到对应locID后立即调用updateWorkshopSelect更新选项
  3. 初始化工作坊选择器时只添加默认提示选项,避免在locID未赋值时执行无效筛选
  4. 新增break语句优化地点ID查找逻辑,找到匹配项后立即停止循环

内容的提问来源于stack exchange,提问作者Driek van der Meulen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:05:22