为什么我的方法 运行 两次并重置了我要更改的对象值?
Why is my method running twice and resetting the object value I'm trying to change?
我声明了一个名为 gameRooms 的对象,其中包含表示房间及其属性的对象。然后我声明 gameState 并为 'currentRoom.' 包含一个 属性 当游戏开始时,我通过 ChangeRoom()
方法将 'currentRoom' 变量设置为 'Graveyard',它只是工作很好。
但是,当我单击一个按钮来执行房间 func
属性 中声明的函数时,函数会写入:
“你进入大殿。
你进入墓地。”
...到 window。当我查看控制台时,我仍在墓地中。为什么?
JSfiddle 在这里:https://jsfiddle.net/SirenKing/fz8pg05L/2/
gameRooms = {
Graveyard: {
description: 'The graveyard is small, enclosed by tall walls. The tombstones are weathered and worn. The names are hard to make out. An abandoned shed sits in one corner. A closed door leads into the castle.',
name: "Graveyard",
navButtons: [
{
name: "Go Inside",
state: "locked",
func: function () {
ChangeRoom( gameRooms.MainHall );
},
id: "tomainhall",
},
(etc etc etc, more rooms and buttons...)
],
},
}
gameState = {
State: {
currentRoom: null,
actionIDs: [ "wakeup" ],
navigationIDs: [],
inventoryIDs: [],
globalMenuIDs: [],
health: 100,
}
};
function ChangeRoom( room ) {
gameState.State.currentRoom = room;
Say( "You enter the " + room.name );
UpdateNavigation( );
UpdateActions( );
return gameState.State.currentRoom;
};
function Say(content) {
let comment = content;
let newParagraph = document.createElement('p');
newParagraph.textContent = comment;
let newestParagraph = document.getElementById("narrative").appendChild(newParagraph);
document.getElementById("narrative").id = "old";
newestParagraph.id = "narrative";
scrollTo(0,document.body.scrollHeight);
};
HTML和按钮构造方法在这里:
<html>
<body>
<div style="width:40%;" id="narrative"></div>
<div id="nav" style="top:200px; right:100px; position:fixed;">
<label>Navigate</label>
</div>
</body>
</html>
function UpdateNavigation( ) {
let oldNavigation = gameState.State.navigationIDs;
console.log(oldNavigation);
console.log("removing old nav buttons by id");
for (i = 0; i < oldNavigation.length; i++) {
// for ids in gameState.State.navigationIDs, remove the button elements by those ids
let elem = document.getElementById( gameState.State.navigationIDs[i] );
elem.remove();
}
gameState.State.navigationIDs = [];
let navs = GetCurrentRoom().navButtons;
let roomName = GetCurrentRoom().name;
console.log( roomName, "'s navButtons are ", navs);
console.log("building new list of nav button ids");
for (i = 0; i < navs.length; i++) {
gameState.State.navigationIDs.push( navs[i].id );
};
let currentNavigation = gameState.State.navigationIDs;
console.log(currentNavigation);
console.log("building nav buttons from list of ids");
for (i = 0; i < currentNavigation.length; i++) {
// for objects in room.navButtons, create new action buttons with ids of the rooms you can enter
// add innerHTML and onclick and type to the button, then append it into the navsDiv
elem = document.createElement("button");
elem.innerHTML = navs[i].name ;
elem.type = "button";
elem.id = currentNavigation[i];
elem.onclick = GetCurrentRoom().navButtons[i].func;
let navsDiv = document.getElementById( "nav" );
navsDiv.lastElementChild.appendChild(elem);
};
};
您的代码有一些问题; Say()
对它的第二个参数没有任何作用,应该这样做,或者连接发送给它的参数:function Say(one, two) { return one + two; }
或 Say(one + two);
...但主要是,最大的问题是你追加你的按钮到 label
元素。
如果此元素不是标签,您的代码将毫无问题地运行。这是因为 label 元素将点击或触摸事件传播到其中的元素,因此每次单击该标签元素中的任一按钮时,该元素都会同时单击两个按钮。
因此,简单的解决方法是删除将按钮附加到标签的代码:
navsDiv.lastElementChild.appendChild(elem);
应改为:
navsDiv.appendChild(elem);
这当然适用于将按钮附加到标签元素的任何代码。同样相关的是您的 UpdateActions()
功能,您可以在其中将内容附加到最后一个 child... 标签。
我声明了一个名为 gameRooms 的对象,其中包含表示房间及其属性的对象。然后我声明 gameState 并为 'currentRoom.' 包含一个 属性 当游戏开始时,我通过 ChangeRoom()
方法将 'currentRoom' 变量设置为 'Graveyard',它只是工作很好。
但是,当我单击一个按钮来执行房间 func
属性 中声明的函数时,函数会写入:
“你进入大殿。
你进入墓地。”
...到 window。当我查看控制台时,我仍在墓地中。为什么?
JSfiddle 在这里:https://jsfiddle.net/SirenKing/fz8pg05L/2/
gameRooms = {
Graveyard: {
description: 'The graveyard is small, enclosed by tall walls. The tombstones are weathered and worn. The names are hard to make out. An abandoned shed sits in one corner. A closed door leads into the castle.',
name: "Graveyard",
navButtons: [
{
name: "Go Inside",
state: "locked",
func: function () {
ChangeRoom( gameRooms.MainHall );
},
id: "tomainhall",
},
(etc etc etc, more rooms and buttons...)
],
},
}
gameState = {
State: {
currentRoom: null,
actionIDs: [ "wakeup" ],
navigationIDs: [],
inventoryIDs: [],
globalMenuIDs: [],
health: 100,
}
};
function ChangeRoom( room ) {
gameState.State.currentRoom = room;
Say( "You enter the " + room.name );
UpdateNavigation( );
UpdateActions( );
return gameState.State.currentRoom;
};
function Say(content) {
let comment = content;
let newParagraph = document.createElement('p');
newParagraph.textContent = comment;
let newestParagraph = document.getElementById("narrative").appendChild(newParagraph);
document.getElementById("narrative").id = "old";
newestParagraph.id = "narrative";
scrollTo(0,document.body.scrollHeight);
};
HTML和按钮构造方法在这里:
<html>
<body>
<div style="width:40%;" id="narrative"></div>
<div id="nav" style="top:200px; right:100px; position:fixed;">
<label>Navigate</label>
</div>
</body>
</html>
function UpdateNavigation( ) {
let oldNavigation = gameState.State.navigationIDs;
console.log(oldNavigation);
console.log("removing old nav buttons by id");
for (i = 0; i < oldNavigation.length; i++) {
// for ids in gameState.State.navigationIDs, remove the button elements by those ids
let elem = document.getElementById( gameState.State.navigationIDs[i] );
elem.remove();
}
gameState.State.navigationIDs = [];
let navs = GetCurrentRoom().navButtons;
let roomName = GetCurrentRoom().name;
console.log( roomName, "'s navButtons are ", navs);
console.log("building new list of nav button ids");
for (i = 0; i < navs.length; i++) {
gameState.State.navigationIDs.push( navs[i].id );
};
let currentNavigation = gameState.State.navigationIDs;
console.log(currentNavigation);
console.log("building nav buttons from list of ids");
for (i = 0; i < currentNavigation.length; i++) {
// for objects in room.navButtons, create new action buttons with ids of the rooms you can enter
// add innerHTML and onclick and type to the button, then append it into the navsDiv
elem = document.createElement("button");
elem.innerHTML = navs[i].name ;
elem.type = "button";
elem.id = currentNavigation[i];
elem.onclick = GetCurrentRoom().navButtons[i].func;
let navsDiv = document.getElementById( "nav" );
navsDiv.lastElementChild.appendChild(elem);
};
};
您的代码有一些问题; Say()
对它的第二个参数没有任何作用,应该这样做,或者连接发送给它的参数:function Say(one, two) { return one + two; }
或 Say(one + two);
...但主要是,最大的问题是你追加你的按钮到 label
元素。
如果此元素不是标签,您的代码将毫无问题地运行。这是因为 label 元素将点击或触摸事件传播到其中的元素,因此每次单击该标签元素中的任一按钮时,该元素都会同时单击两个按钮。
因此,简单的解决方法是删除将按钮附加到标签的代码:
navsDiv.lastElementChild.appendChild(elem);
应改为:
navsDiv.appendChild(elem);
这当然适用于将按钮附加到标签元素的任何代码。同样相关的是您的 UpdateActions()
功能,您可以在其中将内容附加到最后一个 child... 标签。