簡體   English   中英

根據對象狀態在js / html中動態創建按鈕

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM