如何调用DND5 API获取数据填充用户选择下拉菜单
DnD 5e 角色生成器下拉选项实现方案
核心实现逻辑拆成4个部分,所有代码可以直接复制使用:
- 封装通用fetch请求函数,统一处理API调用和错误
- 准备页面表单结构,每个配置项对应下拉菜单+随机勾选框
- 页面初始化时并行拉取职业、种族、阵营数据,填充下拉选项
- 绑定复选框事件,实现勾选后随机选中选项的功能
1. 通用API请求封装
DND5e API不需要鉴权,所有接口的基础路径固定,先封装通用请求函数避免重复代码:
const API_BASE = 'https://www.dnd5eapi.co/api'; async function fetchDndData(endpoint) { try { const response = await fetch(`${API_BASE}${endpoint}`); if (!response.ok) throw new Error(`请求错误:${response.status}`); return await response.json(); } catch (error) { console.error('数据拉取失败:', error); return { results: [] }; } }
所有列表类接口(职业、种族、阵营)返回的数据结构一致,选项都存在results字段中,每个选项包含name(显示名称)和index(唯一标识,用于后续请求详情)两个核心字段。
2. 页面HTML结构
每个选择模块保持统一结构,方便后续复用逻辑:
<div class="select-group"> <label>职业:</label> <select id="classSelect"></select> <label><input type="checkbox" id="randomClass"> 随机生成</label> </div> <div class="select-group"> <label>种族:</label> <select id="raceSelect"></select> <label><input type="checkbox" id="randomRace"> 随机生成</label> </div> <div class="select-group"> <label>阵营:</label> <select id="alignmentSelect"></select> <label><input type="checkbox" id="randomAlignment"> 随机生成</label> </div>
3. 下拉选项填充逻辑
写通用的下拉填充函数,页面加载完成后并行拉取三类数据,比串行请求速度更快:
// 通用下拉填充方法 function fillSelectOptions(selectElement, optionList) { selectElement.innerHTML = '<option value="">请选择</option>'; optionList.forEach(option => { const opt = document.createElement('option'); opt.value = option.index; opt.textContent = option.name; selectElement.appendChild(opt); }); } // 初始化表单数据 async function initCharacterForm() { // 并行请求三类数据,减少等待时间 const [classes, races, alignments] = await Promise.all([ fetchDndData('/classes'), fetchDndData('/races'), fetchDndData('/alignments') ]); // 分别填充对应下拉框 fillSelectOptions(document.getElementById('classSelect'), classes.results); fillSelectOptions(document.getElementById('raceSelect'), races.results); fillSelectOptions(document.getElementById('alignmentSelect'), alignments.results); }
4. 随机选择功能实现
勾选随机复选框时,直接从已经加载到本地的选项中随机选值,不需要重复发起请求,同时禁用下拉框避免手动修改冲突:
// 绑定单个选择组的随机逻辑 function bindRandomSelect(checkboxId, selectId) { const checkbox = document.getElementById(checkboxId); const select = document.getElementById(selectId); checkbox.addEventListener('change', () => { if (checkbox.checked) { // 过滤掉默认的"请选择"占位项 const validOptions = Array.from(select.options).slice(1); if (!validOptions.length) return; // 生成随机索引选中对应选项 const randomPos = Math.floor(Math.random() * validOptions.length); select.value = validOptions[randomPos].value; select.disabled = true; } else { // 取消勾选恢复可编辑状态 select.disabled = false; select.value = ''; } }); } // DOM加载完成后执行初始化 document.addEventListener('DOMContentLoaded', () => { initCharacterForm(); // 为三个选择组绑定随机事件 bindRandomSelect('randomClass', 'classSelect'); bindRandomSelect('randomRace', 'raceSelect'); bindRandomSelect('randomAlignment', 'alignmentSelect'); });
注意事项:如果本地直接打开HTML文件遇到跨域报错,用本地静态服务(比如VS Code的Live Server插件)启动页面即可,该API本身支持跨域调用,不需要额外配置密钥或请求头。后续如果需要获取某个选项的详细规则(比如职业的技能熟练度、种族属性加成),直接拿选中项的
value拼接接口路径请求即可,例如选中战士后请求/classes/fighter就能拿到对应完整数据。
内容的提问来源于stack exchange,提问作者mellimel
相关产品推荐
相关产品推荐

