提问人:OADINC 提问时间:6/24/2023 最后编辑:Mark SchultheissOADINC 更新时间:6/24/2023 访问量:59
HTML/JS:从对象创建下拉菜单
HTML/JS: Making a dropdown menu from object
问:
[背景]
我正在尝试建立一个 RailRoadsOnline Train Builder 网站。您可以在哪里选择机车和货车。然后它会计算您是否可以取得某些成绩。我计划稍后添加更多功能,但首先是基础知识。这是我用HTML/JS做的第一个项目。我确实有C / C++ + + / Py/VHDL的经验。
[问题]
我在生成由按钮生成的下拉列表时遇到了问题,这是为了让 locs/wagons 的数量动态而不是硬编码。
当我预设按钮时,我希望它制作一个下拉列表,该列表从对象中获取其内容列表。下拉列表必须显示Display_Name值,但在读取自时返回密钥。对象示例(抽象/示例值) 因此,当您在代码中选择 Porter 1 时,它将返回/读出为Porter_1{Important_Key_Name_I_Need_Later: {Display_Name: "The Name", ...}, Porter_1: {Display_Name: "Porter 1", Mass: 7242, Length: 4, Tractive_Effort: 12.8}, ...}
我已经从这个中调整了我的代码,这有效,但现在我正在生成整个下拉列表,它中断了。
这是代码,对不起,它有点多:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Web Page</title>
</head>
<body>
<form>
<input type="button" id="Calculate" value="Calculate">
<p> Total Weight</p>
<p id="Loc_Sel">Selected Loc</p>
<input type="button" id="Add_Locomotive" value="Add a locomotive">
<input type="button" id="Add_Wagon" value="Add a wagon">
<input type="button" id="Reset" value="Reset">
</form>
</script>
<div id="Button_Div"></div>
<script type="text/javascript">
//Locomotives
let Locomotives = {
Porter_1: {Mass: 7242, Length: 4, Tractive_Effort: 12.8, Display_Name: "Porter 1"},
Porter_2: {Mass: 8145, Length: 4.8, Tractive_Effort: 12.8, Display_Name: "Porter 2"},
Montezuma: {Mass: 14969, Length: 11, Tractive_Effort: 16.2, Display_Name: "Montezuma"},
Shay: {Mass: 21754, Length: 8.1, Tractive_Effort: 26.2, Display_Name: "Shay"},
Tenmile: {Mass: 19848, Length: 11.8, Tractive_Effort: 37.7, Display_Name: "Tenmile"},
Eureka: {Mass:17164 , Length: 13.1, Tractive_Effort: 25, Display_Name: "Eureka"},
Glenbrook: {Mass: 17128, Length: 13.5, Tractive_Effort: 34.1, Display_Name: "Glenbrook"},
DRGW_Class_48: {Mass: 14969, Length: 7.7, Tractive_Effort: 41.7, Display_Name: "D&RGW Class 48"},
Mosca: {Mass: 25348, Length: 13.8, Tractive_Effort: 38.3, Display_Name: "Mosca"},
Cooke_Mogul: {Mass: 26388, Length: 15.1, Tractive_Effort: 52.8, Display_Name: "Cooke Mogul"},
Heisler: {Mass: 28064, Length: 9.1, Tractive_Effort: 57.9, Display_Name: "Heisler"},
Ruby_Basin: {Mass: 33042, Length: 10.3, Tractive_Effort: 60.1, Display_Name: "Ruby Basin"},
Cooke_Consilidation: {Mass: 26706, Length: 15.1, Tractive_Effort: 59.9, Display_Name: "Cooke Consilidation"},
Climax: {Mass: 24194, Length: 8.7, Tractive_Effort: 76.6, Display_Name: "Climax"},
DRG_Class_70: {Mass: 15468, Length: 15.6, Tractive_Effort: 68.8, Display_Name: "D&RG Class 70"},
ETWNC_2_8_0: {Mass: 16545, Length: 16.2, Tractive_Effort: 73.6, Display_Name: "ET&WNC 2-8-0"}
};
//Wagons
let Wagons = {
No_Car: {Mass: 0, Length: 0, Display_Name: "No_Car", Cargo: {}},
Skeleton_Car: {Mass: 3000, Length: 6.4, Display_Name: "Skeleton Car", Cargo: {Logs: 5}},
Flatcar_Rounds: {Mass: 3800, Length: 8.4, Display_Name: "Flatcar Rounds", Cargo: {Logs: 6, Steel_Pipes: 9}},
Flatcar_Stakes: {Mass: 4000, Length: 8.4, Display_Name: "Flatcar Stakes", Cargo: {Lumber: 6, Beams: 3, Raw_Iron: 3, Rails: 10}},
Flatcar_Bulkhead: {Mass: 4100, Length: 8.4, Display_Name: "Flatcar Bulkhead", Cargo: {Cordwood: 6, Oil_Barrels: 46}},
Hopper: {Mass: 6000, Length: 8.2, Display_Name: "Hopper", Cargo: {Iron_ore: 10, Coal_Ore: 10}},
EBT_Hopper: {Mass: 6000, Length: 7.75, Display_Name: "EBT Hopper", Cargo: {Iron_ore: 8, Coal_Ore: 10}},
Tanker: {Mass: 13968, Length: 8.1, Display_Name: "Tanker", Cargo: {Crude_Oil: 12}},
Coffin_Tank_Car: {Mass: 14250, Length: 10, Display_Name: "Coffin Tank Car", Cargo: {Crude_Oil: 8}},
Box_Car: {Mass: 7938, Length: 8.1, Display_Name: "Box Car", Cargo: {Tool_Crates: 32}},
Stock_Car: {Mass: 8000, Length: 9.4, Display_Name: "Stock Car", Cargo: {Tool_Crates: 32}},
Bobber_Caboose: {Mass: 5400, Length: 6.8, Display_Name: "Bobber Caboose", Cargo: {}},
DSPP_Waycar: {Mass: 5000, Length: 6.1, Display_Name: "DSP&P Waycar", Cargo: {}},
Snow_Plow: {Mass: 6000, Length: 6, Display_Name: "Snow Plow", Cargo: {}}
};
//Cargo Types
let Cargo_Types = {
Logs: {Money: 10, Mass: 2000, Display_Name: "Logs"},
Cordwood: {Money: 10, Mass: 1200, Display_Name: "Cordwood"},
Beams: {Money: 24, Mass: 1410, Display_Name: "Beams"},
Lumber: {Money: 12, Mass: 1350, Display_Name: "Lumber"},
Iron_Ore: {Money: 20, Mass: 1000, Display_Name: "Iron Ore"},
Coal_Ore: {Money: 15, Mass: 1000, Display_Name: "Coal Ore"},
Raw_Iron: {Money: 25, Mass: 1490, Display_Name: "Raw Iron"},
Rails: {Money: 25, Mass: 900, Display_Name: "Rails"},
Steel_Pipes: {Money: 40, Mass: 1800, Display_Name: "Steel Pipes"},
Tool_Crates: {Money: 30, Mass: 100, Display_Name: "Tool Crates"},
Crude_Oil: {Money: 25, Mass: 1000, Display_Name: "Crude Oil"},
Oil_Barrels: {Money: 40, Mass: 137, Display_Name: "Oil Barrels"}
};
let Vehicles = {Loc: -1, Wag: -1};
const Button_Calculate = document.getElementById('Calculate');
const Button_Add_Locomotive = document.getElementById('Add_Locomotive');
const Button_Add_Wagon = document.getElementById('Add_Wagon');
const Button_Reset = document.getElementById('Reset');
//This is the adapted version of the linked code.
function Mk_DropDown(Id, Dictionairy){
var Options = document.getElementById(Id);
Object.keys(Dictionairy).forEach(key => {
Options.appendChild(new Option(Dictionairy[key]['Display_Name'], key));
});
}
//This function should not becausing issues, just included for completeness.
function changeText(element, value) {
document.getElementById(element).innerHTML = value;
}
//This function should not becausing issues, just included for completeness.
function Calculate_Train_Weight() {
let Weight = 0;
for(let i = 0; i < Vehicles['Loc']; i++) {
Locomotives[document.getElementById("Select_Loc_" + i).value]['Mass'];
}
for(let i = 0; i < Vehicles['Wag']; i++) {
Wagons[document.getElementById("Select_Wagon_" + i).value]['Mass'];
}
return Weight;
}
//This function should not becausing issues, just included for completeness.
function Calculate() {
changeText('Loc_Sel', Calculate_Train_Weight());
}
function Add_Locomotive() {
Vehicles['Loc']++;
console.log(Vehicles['Loc']);
document.getElementById("Button_Div").innerHTML = "<select> id=\"Select_Locomotive_" + Vehicles['Loc'] + "<option>Choose a locomotive</option></select>" + document.getElementById("Button_Div").innerHTML
//Is doing it once when creating new box enough or should it loop through al existing dropdowns as well?
Mk_DropDown("Select_Loc_" + Vehicles['Loc'], Locomotives);
}
function Add_Wagon() {
Vehicles['Wag']++;
document.getElementById("Button_Div").innerHTML += "<select> id=\"Select_Wagon_" + Vehicles['Wag'] + "<option>Choose a wagon</option></select>"
//Is doing it once when creating new box enough or should it loop through al existing dropdowns as well?
for(let i = 0; i < Vehicles['Wag']; i++) {
Mk_DropDown("Select_Wagon_" + i, Wagons);
}
}
//This function works but feels like a hack, so if you have suggestions for this feel free to mention it!
function Reset() {
document.getElementById("Button_Div").innerHTML = "";
Vehicles['Loc'] = 0;
Vehicles['Wag'] = 0;
}
Button_Add_Locomotive.addEventListener('click', Add_Locomotive);
Button_Add_Wagon.addEventListener('click', Add_Wagon);
Button_Reset.addEventListener('click', Reset);
Button_Calculate.addEventListener('click', Calculate);
</script>
</body>
</html>
答:
老实说,这个实现有点卡顿,但你的主要问题是你连接字符串的方式。您正在以一种无法找到已传递的元素的方式连接字符串。Mk_DropDown
id
在中,您需要传递一个与您分配给元素的内容一致的内容。您已为每次按下带有前缀的按钮分配了 s,以迭代 。我将把它改成像传入的内容一样.Add_Locomotive
id
select
id
Select_Locomotive_[someindex]
Select_Loc_[someindex]
Mk_DropDown
第二个问题是属性需要位于前导标记内。id
select
第三个问题是反斜杠异常需要关闭 以及 start。id
修订后的内容可能如下所示:Add_Locomotive
function Add_Locomotive() {
Vehicles['Loc']++;
console.log(Vehicles['Loc']);
document.getElementById("Button_Div").innerHTML = "<select " + "id=\"Select_Loc_" + Vehicles['Loc'] + "\" >" + "<option>Choose a locomotive</option></select>" + document.getElementById("Button_Div").innerHTML
Mk_DropDown("Select_Loc_" + Vehicles['Loc'], Locomotives);
}
为了进一步简化,我将使用字符串插值:
function Add_Locomotive() {
Vehicles['Loc']++;
console.log(Vehicles['Loc']);
document.getElementById("Button_Div").innerHTML = `<select id="Select_Loc_${Vehicles['Loc']}" > <option>Choose a locomotive</option></select>` + document.getElementById("Button_Div").innerHTML
Mk_DropDown("Select_Loc_" + Vehicles['Loc'], Locomotives);
}
我无法判断你是否只是在你的实现中尝试一些东西,或者你是否在测试性能,但你需要在 to 中更改你的相等性检查,否则它不会运行,因为添加第一个货车将使 ,它不小于 并且你的循环仅在 .Add_Wagon
for loop
i <= Vehicles['Wag']
Vehicles['Wag'] === 0
0
i < 0
function Add_Wagon() {
Vehicles['Wag']++;
document.getElementById("Button_Div").innerHTML += `<select id="Select_Wagon_${Vehicles['Wag']}" > <option>Choose a wagon</option></select>`
for (let i = 0; i <= Vehicles['Wag']; i++) {
Mk_DropDown("Select_Wagon_" + i, Wagons);
}
}
最后,您的函数将中断该函数,因为它会重置对象,而该对象不是重置的,因为它是使用 启动的。进行循环是行不通的,因为您将运行,运行并附加一个子项,然后您将运行该循环,并且要传递给的第一个参数不是DOM中的子项。Reset
Add_Wagon
Vehicles
{"Wag": 0, "Loc": 0}
{"Wag": -1, "Loc": -1}
Add_Wag
Reset
Add_Wagon
id="Select_Wagon_1"
Mk_DropDown
Mk_DropDown("Select_Wagon_0", Wagons)
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Web Page</title>
</head>
<body>
<form>
<input type="button" id="Calculate" value="Calculate">
<p> Total Weight</p>
<p id="Loc_Sel">Selected Loc</p>
<input type="button" id="Add_Locomotive" value="Add a locomotive">
<input type="button" id="Add_Wagon" value="Add a wagon">
<input type="button" id="Reset" value="Reset">
</form>
</script>
<div id="Button_Div"></div>
<script type="text/javascript">
//Locomotives
let Locomotives = {
Porter_1: { Mass: 7242, Length: 4, Tractive_Effort: 12.8, Display_Name: "Porter 1" },
Porter_2: { Mass: 8145, Length: 4.8, Tractive_Effort: 12.8, Display_Name: "Porter 2" },
Montezuma: { Mass: 14969, Length: 11, Tractive_Effort: 16.2, Display_Name: "Montezuma" },
Shay: { Mass: 21754, Length: 8.1, Tractive_Effort: 26.2, Display_Name: "Shay" },
Tenmile: { Mass: 19848, Length: 11.8, Tractive_Effort: 37.7, Display_Name: "Tenmile" },
Eureka: { Mass: 17164, Length: 13.1, Tractive_Effort: 25, Display_Name: "Eureka" },
Glenbrook: { Mass: 17128, Length: 13.5, Tractive_Effort: 34.1, Display_Name: "Glenbrook" },
DRGW_Class_48: { Mass: 14969, Length: 7.7, Tractive_Effort: 41.7, Display_Name: "D&RGW Class 48" },
Mosca: { Mass: 25348, Length: 13.8, Tractive_Effort: 38.3, Display_Name: "Mosca" },
Cooke_Mogul: { Mass: 26388, Length: 15.1, Tractive_Effort: 52.8, Display_Name: "Cooke Mogul" },
Heisler: { Mass: 28064, Length: 9.1, Tractive_Effort: 57.9, Display_Name: "Heisler" },
Ruby_Basin: { Mass: 33042, Length: 10.3, Tractive_Effort: 60.1, Display_Name: "Ruby Basin" },
Cooke_Consilidation: { Mass: 26706, Length: 15.1, Tractive_Effort: 59.9, Display_Name: "Cooke Consilidation" },
Climax: { Mass: 24194, Length: 8.7, Tractive_Effort: 76.6, Display_Name: "Climax" },
DRG_Class_70: { Mass: 15468, Length: 15.6, Tractive_Effort: 68.8, Display_Name: "D&RG Class 70" },
ETWNC_2_8_0: { Mass: 16545, Length: 16.2, Tractive_Effort: 73.6, Display_Name: "ET&WNC 2-8-0" }
};
//Wagons
let Wagons = {
No_Car: { Mass: 0, Length: 0, Display_Name: "No_Car", Cargo: {} },
Skeleton_Car: { Mass: 3000, Length: 6.4, Display_Name: "Skeleton Car", Cargo: { Logs: 5 } },
Flatcar_Rounds: { Mass: 3800, Length: 8.4, Display_Name: "Flatcar Rounds", Cargo: { Logs: 6, Steel_Pipes: 9 } },
Flatcar_Stakes: { Mass: 4000, Length: 8.4, Display_Name: "Flatcar Stakes", Cargo: { Lumber: 6, Beams: 3, Raw_Iron: 3, Rails: 10 } },
Flatcar_Bulkhead: { Mass: 4100, Length: 8.4, Display_Name: "Flatcar Bulkhead", Cargo: { Cordwood: 6, Oil_Barrels: 46 } },
Hopper: { Mass: 6000, Length: 8.2, Display_Name: "Hopper", Cargo: { Iron_ore: 10, Coal_Ore: 10 } },
EBT_Hopper: { Mass: 6000, Length: 7.75, Display_Name: "EBT Hopper", Cargo: { Iron_ore: 8, Coal_Ore: 10 } },
Tanker: { Mass: 13968, Length: 8.1, Display_Name: "Tanker", Cargo: { Crude_Oil: 12 } },
Coffin_Tank_Car: { Mass: 14250, Length: 10, Display_Name: "Coffin Tank Car", Cargo: { Crude_Oil: 8 } },
Box_Car: { Mass: 7938, Length: 8.1, Display_Name: "Box Car", Cargo: { Tool_Crates: 32 } },
Stock_Car: { Mass: 8000, Length: 9.4, Display_Name: "Stock Car", Cargo: { Tool_Crates: 32 } },
Bobber_Caboose: { Mass: 5400, Length: 6.8, Display_Name: "Bobber Caboose", Cargo: {} },
DSPP_Waycar: { Mass: 5000, Length: 6.1, Display_Name: "DSP&P Waycar", Cargo: {} },
Snow_Plow: { Mass: 6000, Length: 6, Display_Name: "Snow Plow", Cargo: {} }
};
//Cargo Types
let Cargo_Types = {
Logs: { Money: 10, Mass: 2000, Display_Name: "Logs" },
Cordwood: { Money: 10, Mass: 1200, Display_Name: "Cordwood" },
Beams: { Money: 24, Mass: 1410, Display_Name: "Beams" },
Lumber: { Money: 12, Mass: 1350, Display_Name: "Lumber" },
Iron_Ore: { Money: 20, Mass: 1000, Display_Name: "Iron Ore" },
Coal_Ore: { Money: 15, Mass: 1000, Display_Name: "Coal Ore" },
Raw_Iron: { Money: 25, Mass: 1490, Display_Name: "Raw Iron" },
Rails: { Money: 25, Mass: 900, Display_Name: "Rails" },
Steel_Pipes: { Money: 40, Mass: 1800, Display_Name: "Steel Pipes" },
Tool_Crates: { Money: 30, Mass: 100, Display_Name: "Tool Crates" },
Crude_Oil: { Money: 25, Mass: 1000, Display_Name: "Crude Oil" },
Oil_Barrels: { Money: 40, Mass: 137, Display_Name: "Oil Barrels" }
};
let Vehicles = { Loc: -1, Wag: -1 };
const Button_Calculate = document.getElementById('Calculate');
const Button_Add_Locomotive = document.getElementById('Add_Locomotive');
const Button_Add_Wagon = document.getElementById('Add_Wagon');
const Button_Reset = document.getElementById('Reset');
//This is the adapted version of the linked code.
function Mk_DropDown(Id, Dictionairy) {
var Options = document.getElementById(Id);
Object.keys(Dictionairy).forEach(key => {
Options.appendChild(new Option(Dictionairy[key]['Display_Name'], key));
});
}
//This function should not becausing issues, just included for completeness.
function changeText(element, value) {
document.getElementById(element).innerHTML = value;
}
//This function should not becausing issues, just included for completeness.
function Calculate_Train_Weight() {
let Weight = 0;
for (let i = 0; i < Vehicles['Loc']; i++) {
Locomotives[document.getElementById("Select_Loc_" + i).value]['Mass'];
}
for (let i = 0; i < Vehicles['Wag']; i++) {
Wagons[document.getElementById("Select_Wagon_" + i).value]['Mass'];
}
return Weight;
}
//This function should not becausing issues, just included for completeness.
function Calculate() {
changeText('Loc_Sel', Calculate_Train_Weight());
}
function Add_Locomotive() {
Vehicles['Loc']++;
console.log(Vehicles['Loc']);
document.getElementById("Button_Div").innerHTML = `<select id="Select_Loc_${Vehicles['Loc']}" > <option>Choose a locomotive</option></select>` + document.getElementById("Button_Div").innerHTML
//Is doing it once when creating new box enough or should it loop through al existing dropdowns as well?
Mk_DropDown("Select_Loc_" + Vehicles['Loc'], Locomotives);
}
function Add_Wagon() {
Vehicles['Wag']++;
document.getElementById("Button_Div").innerHTML += `<select id="Select_Wagon_${Vehicles['Wag']}" > <option>Choose a wagon</option></select>`
//Is doing it once when creating new box enough or should it loop through al existing dropdowns as well?
for (let i = 0; i <= Vehicles['Wag']; i++) {
console.log(i)
Mk_DropDown("Select_Wagon_" + i, Wagons);
}
}
//This function works but feels like a hack, so if you have suggestions for this feel free to mention it!
function Reset() {
document.getElementById("Button_Div").innerHTML = "";
Vehicles['Loc'] = -1;
Vehicles['Wag'] = -1;
}
Button_Add_Locomotive.addEventListener('click', Add_Locomotive);
Button_Add_Wagon.addEventListener('click', Add_Wagon);
Button_Reset.addEventListener('click', Reset);
Button_Calculate.addEventListener('click', Calculate);
</script>
</body>
</html>
评论