Я работаю над движком, который создает файлы карт для игры, которую я сделал. Игра представляет собой текстовое приключение, в котором используется сетка пространств для отображения событий, таких как сообщения, предметы, квесты, враги и т.д.
Форма, над которой я сейчас работаю, создаст сетку с помощью кнопок, поскольку значения будут вводиться в поля ввода - это создает лучшее визуальное представление.
Я работаю над этой функцией, которая делает следующее.
1.) проверяет, была ли указана высота - таким образом, он знает, выполняется ли его рисование линейной комнатой или прямоугольной комнатой перед тем, как что-либо еще выполняется
2.) если это линейная комната (только ширина указана), она использует ширину для создания и добавления кнопок к содержащему элементу.
3.) если он прямоугольный (указаны ширина и высота), выполняется цикл вложенных циклов, который добавляет x количество кнопок для ширины, затем y количество
для высоты.
4.) Когда одна из этих кнопок нажата, она добавляет другую форму к экрану. который затем может быть заполнен пользователем.
вот код для этого
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(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
строка 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>');
Но если вы хотите, чтобы кнопка была в отдельной строке, было бы лучше разместить ее внутри элемента блока, а не добавлять команды br
:
var div = room.subGridContainer.appendChild(document.createElement('div'));
var button = div.appendChild(document.createElement('button'));
// etc
<br/>
В некоторых мнениях считается плохой практикой. Почему БР это плохо