gpt4 book ai didi

javascript - 根据对象状态在js/html中动态创建按钮

转载 作者:行者123 更新时间:2023-12-03 08:21:03 24 4
gpt4 key购买 nike

我遇到以下情况,无法解决。我对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++;
}
}

}

我在另一段设置 ids 的代码中制作了按钮:

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();
}

}

我遇到的问题是,如果两个对象都处于事件状态==true,我会在横幅中收到两条不同的消息和两个按钮,但按下它们总是会触发 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 的当前值传递给立即执行的函数来将其绑定(bind)到新变量,因此两个 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;
}

关于javascript - 根据对象状态在js/html中动态创建按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33748196/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com