基于Skyrim炼金术的JS程序中Select下拉框无法填充问题排查
问题:Skyrim炼金术JS程序下拉框无法填充选项
我正在编写一个基于《上古卷轴5:天际》(Skyrim)炼金术机制的JavaScript程序,功能是让用户从下拉菜单选择两种配料调配,但页面中id为ing1和ing2的<select>下拉框始终无法被填充选项。JS中的for循环能正常打印日志,但无法向下拉框添加<option>元素。
代码示例
HTML代码
<head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script src="alchemy.js"></script> </head> <body> <select id="ing1"></select> <select id="ing2"></select> <button onClick="mix()">Mix</button> </body>
JavaScript代码(alchemy.js)
class Ingredient{ constructor(effect1, effect2, effect3, effect4){ this.effect1 = effect1; this.effect2 = effect2; this.effect3 = effect3; this.effect4 = effect4; } effectMatcher(otherAgentEffect) { switch(otherAgentEffect) { case this.effect1: alert("You created a " + this.effect1 + " potion!"); break; case this.effect2: alert("You created a " + this.effect2 + " potion!"); break; case this.effect3: alert("You created a " + this.effect3 + " potion!"); break; case this.effect4: alert("You created a " + this.effect4 + " potion!"); break; } } mix(secondAgent) { this.effectMatcher(secondAgent.effect1); this.effectMatcher(secondAgent.effect2); this.effectMatcher(secondAgent.effect3); this.effectMatcher(secondAgent.effect4); } } const wheat = new Ingredient("restore health", "invisibility", "resist fire", "resist frost") const torchbug_thorax = new Ingredient("damage health", "resist magic", "resist shock", "restore fatigue") const frost_mirmain = new Ingredient("resist frost", "restore fatigue", "restore magicka", "resist fire") const lavender = new Ingredient("fortify conjuration", "restore health", "restore fatigue", "restore magicka") const dwemer_oil = new Ingredient("fortify one-handed", "damage health", "damage fatigue", "restore magicka") let ingArray = ["wheat", "torchbug_thorax", "frost_mirmain", "lavender", "dwemer_oil"]; for (let i = 0; i < ingArray.length; i++) { console.log("for loop firing"); console.log(ingArray[i]); $("#ing1").append("<option value='" + i + "'>" + ingArray[i] + "</option>") $("#ing2").append("<option value='" + i + "'>" + ingArray[i] + "</option>") } function mix() { ingArray[parseInt(document.getElementById("ing1").value)].mix(ingArray[parseInt(document.getElementById("ing2").value)]) }
原因分析
核心问题是代码执行时机过早:你的alchemy.js脚本放在<head>标签中加载,此时浏览器还未解析<body>里的<select>元素,jQuery选择器$("#ing1")和$("#ing2")无法找到对应的DOM节点,因此无法添加<option>选项。
解决方案
方案1:将脚本移至<body>末尾
把alchemy.js的引用放到</body>标签前,确保DOM完全加载后再执行JS代码:
<body> <select id="ing1"></select> <select id="ing2"></select> <button onClick="mix()">Mix</button> <script src="alchemy.js"></script> </body>
方案2:用$(document).ready()包裹DOM操作代码
在alchemy.js中,把填充下拉框的逻辑放到jQuery的ready回调里,确保DOM就绪后再执行:
$(document).ready(function() { let ingArray = ["wheat", "torchbug_thorax", "frost_mirmain", "lavender", "dwemer_oil"]; for (let i = 0; i < ingArray.length; i++) { console.log("for loop firing"); console.log(ingArray[i]); $("#ing1").append("<option value='" + i + "'>" + ingArray[i] + "</option>") $("#ing2").append("<option value='" + i + "'>" + ingArray[i] + "</option>") } });
方案3:给脚本添加defer属性
在<head>里的脚本标签添加defer属性,让脚本等待DOM解析完成后再执行:
<script src="alchemy.js" defer></script>
额外修复:mix函数的潜在问题
当前ingArray存储的是字符串(如"wheat"),但wheat是Ingredient实例对象,直接调用ingArray[...].mix()会报错。需要调整ingArray存储实例,并单独维护选项文本:
// 存储Ingredient实例 let ingArray = [wheat, torchbug_thorax, frost_mirmain, lavender, dwemer_oil]; // 对应选项显示的名称 let ingNames = ["wheat", "torchbug_thorax", "frost_mirmain", "lavender", "dwemer_oil"]; // 填充下拉框 for (let i = 0; i < ingArray.length; i++) { $("#ing1").append("<option value='" + i + "'>" + ingNames[i] + "</option>") $("#ing2").append("<option value='" + i + "'>" + ingNames[i] + "</option>") }
内容的提问来源于stack exchange,提问作者DennisM
相关产品推荐
相关产品推荐

