[英]Dynamically create buttons in js/html based on object state
我有以下無法解決的情況。 我對js比較陌生。 我有一個在網頁上運行的js。 按下KB快捷方式后,腳本將運行。 修改了一些內容之后,它會彈出一個html橫幅,我要根據用戶在其上運行腳本的內容在其中放置某些消息和按鈕。 對於一個簡單的情況,假設在此彈出窗口中可以有兩個潛在的消息。 我在對象數組中有詳細信息:
NH_Bann = {
STC: {
active: false,
bannText: "Force Title Case: ",
id: "toTitleCaseStrong",
value: "Yes",
action: function() {
var newNameStr = toTitleCaseStrong(vname);
if (newNameStr !== name) {
//**update function
NH_Bann.STC.active = false;
}
}
},
DTC: {
active: false,
bannText: "Enable DTC? ",
id: "addDTC",
value: "Yes",
action: function() {
//**update function
NH_Bann.DTC.active = false;
}
}
}
運行腳本時,有一些if語句可以將活動鍵更改為true。 腳本運行后,我要遍歷NH_Bann中的對象,如果活動鍵為true,則發出帶有觸發該動作按鈕的動作按鈕的消息。 我遇到的問題是動態制作按鈕。 從其他線程來看,我認為我可以將按鈕存儲在數組中,但是也許onclick不能那樣工作? 這就是我所擁有的:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = function(){
NH_Bann[tempKey].action();
assembleBanner(); // makes the html for the banner
}
ixButt++;
}
}
}
我在設置id的另一段代碼中創建按鈕:
function assembleBanner() {
sidebarMessageEXT = [sidebarMessage.slice(0)];
var EXTOption = false;
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
sidebarMessageEXT.push(NH_Bann[tempKey].bannText + '<input id="' + NH_Bann[tempKey].id + '" type="button" value="' + NH_Bann[tempKey].value + '">');
EXTOption = true;
}
}
if (EXTOption) {
sidebarMessageEXT = sidebarMessageEXT.join("<li>");
displayBanners(sidebarMessageEXT,severity);
setupButtons();
} else {
displayBanners(sidebarMessage,severity);
setupButtons();
}
}
我遇到的問題是,如果兩個對象都處於活動狀態,則我會在橫幅中看到兩個不同的消息和兩個按鈕,但是按它們總是會觸發DTC對象的更新功能。 有什么建議么? 我可以使用其他方法,但是我需要能夠隨時間添加到對象列表中,並根據每個對象的活動鍵狀態有條件地顯示按鈕。 謝謝!
問題與閉包有關。 在此代碼中:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = function(){
NH_Bann[tempKey].action();
assembleBanner(); // makes the html for the banner
}
ixButt++;
}
}
}
... tempKey
是位於setupButtons
調用中的變量。 請注意,您正在循環中創建兩個onclick
函數回調,並且兩者都引用tempKey
。 但是, 在函數創建時 ,它們將不會引用變量的值 ,而只會引用變量的 最新值 。 因此,一旦循環完成, tempKey
將引用其擁有的最后一個值。
要解決此問題,您可以使用此技巧為每個具有正確值的onclick
創建一個新的閉合:
function setupButtons() {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++ ) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn[ixButt] = document.getElementById(NH_Bann[tempKey].id);
btn[ixButt].onclick = (function(buttonId) {
return function() {
NH_Bann[buttonId].action();
assembleBanner(); // makes the html for the banner
}
})(tempKey);
ixButt++;
}
}
}
本質上,這是通過將tempKey
的當前值傳遞給立即執行的函數來將其tempKey
到新變量,因此,兩個onclick
函數不再引用循環中更改的變量。
對於執行此操作的方法,您可以將每個按鈕的創建移到其自己的命名函數中,並傳遞所需的數據:
function setupButtons() {
var btn = [];
for (var NHix = 0; NHix < Object.keys(NH_Bann).length; NHix++) {
tempKey = Object.keys(NH_Bann)[NHix];
if (NH_Bann[tempKey].active) {
btn.push(setupButton(NH_Bann[tempKey]);
}
}
}
function setupButton(bannerData) {
var button = document.getElementById(bannerData.id);
button.onclick = function() {
bannerData.action();
assembleBanner();
};
return button;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.