我正在开发一种引擎,可以为我制作的游戏创建 map 文件。该游戏是一种基于文本的冒险游戏,它使用空间网格来显示消息、元素、任务、敌人等事件。
我现在正在处理的表单将使用按钮创建一个网格,因为将值输入到输入字段中 - 这会创建更好的视觉表示。
我正在研究执行以下操作的函数。
检查是否指定了高度 - 这样它就知道在执行任何其他操作之前绘制的是线性房间还是矩形房间
如果它是线性房间(仅指定了宽度),它会使用宽度来创建按钮并将其附加到包含元素。
如果它是矩形(已指定宽度和高度),则运行嵌套的 for 循环,为宽度附加 x 个按钮,然后为高度附加 y 个
。单击其中一个按钮时,它会在屏幕上附加另一个表单。然后可以由用户填写。
代码如下:
var creategridwidth = function(room)
{
//store the room in a local variable
var room = room;
//while the grid container has children in it
while(room.subGridContainer.hasChildNodes())
{
//remove the children from the container
room.subGridContainer.removeChild(room.subGridContainer.lastChild);
}
//if the room height has already been set
if(room.heightValue > 0)
{
//loop through the amount of rows
for(var x = 0; x < room.heightValue; x ++)
{
//loop through the amount of columns
for(var y = 0; y < room.widthValue; y ++)
{
//create a new button element
var button = document.createElement('button')
//assign the button element to the grid class
button.setAttribute("class", "grid");
//add an event listener for on click to view input information
button.addEventListener('click', function()
{
console.log("click")
//run add space input function to add the html form to the page.
addspaceinput(room);
}, false);
//display the button as inline block so that they are side by side
button.style.display = "inline-block";
//append the button to the grid container
room.subGridContainer.appendChild(button);
}
//when the row has been added, add a line break to start the next lie.
room.subGridContainer.innerHTML += "<br>";
}
//if the height has not already been set
} else {
//loop through the width of the room
for(var z = 0; z < room.widthValue; z ++)
{
//create a new button element
var button = document.createElement('button')
//assign the button element to the grid class
button.setAttribute("class", "grid");
//add an event listener for on click to view input information
button.addEventListener('click', function()
{
console.log("click")
//run add space input function to add the html form to the page.
addspaceinput(room);
}, false);
//display the button as inline block so that they are side by side
button.style.display = "inline-block";
//append the button to the grid container
room.subGridContainer.appendChild(button);
}
}
}
现在,我遇到麻烦的部分是发生在嵌套 for 循环中的事件监听器。
例如:
for(var z = 0; z < room.widthValue; z ++)
{
//create a new button element
var button = document.createElement('button')
//assign the button element to the grid class
button.setAttribute("class", "grid");
//add an event listener for on click to view input information
button.addEventListener('click', function()
{
console.log("click")
//run add space input function to add the html form to the page.
addspaceinput(room);
}, false);
//display the button as inline block so that they are side by side
button.style.display = "inline-block";
//append the button to the grid container
room.subGridContainer.appendChild(button);
}
我可以在控制台中看到此日志,效果很好。 然而:
for(var x = 0; x < room.heightValue; x ++)
{
//loop through the amount of columns
for(var y = 0; y < room.widthValue; y ++)
{
//create a new button element
var button = document.createElement('button')
//assign the button element to the grid class
button.setAttribute("class", "grid");
//add an event listener for on click to view input information
button.addEventListener('click', function()
{
console.log("click")
//run add space input function to add the html form to the page.
addspaceinput(room);
}, false);
//display the button as inline block so that they are side by side
button.style.display = "inline-block";
//append the button to the grid container
room.subGridContainer.appendChild(button);
}
//when the row has been added, add a line break to start the next lie.
room.subGridContainer.innerHTML += "<br>";
}
这完全没有任何行为。我不确定如何推进这个。 如果对此有任何建议,我将不胜感激。
最佳答案
问题出在这里:
room.subGridContainer.innerHTML += "<br>";
当您分配给 innerHTML
时,现有的 innerHTML
被检索,元素被清除,然后是新的连接的 innerHTML
字符串被解析为DOM。因此,任何引用内部元素的变量都将丢失,包括曾经具有事件监听器的元素。
const button = document.body.appendChild(document.createElement('button'));
button.textContent = 'click';
button.onclick = () => console.log('clicked');
// the next line will break the listener:
document.body.innerHTML += '<br>';
改为显式附加元素:
room.subGridContainer.appendChild(document.createElement('br'));
另一种选择是insertAdjacentHTML
:
room.subGridContainer.insertAdjacentHTML('beforeend', '<br>');
但是如果你想让按钮独占一行,最好将它放在 block 元素中,而不是附加 br
s:
var div = room.subGridContainer.appendChild(document.createElement('div'));
var button = div.appendChild(document.createElement('button'));
// etc
关于javascript - button.addEventListener 在嵌套 for 循环中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50869761/