button.addEventListener не работает во вложенном цикле

1

Я работаю над движком, который создает файлы карт для игры, которую я сделал. Игра представляет собой текстовое приключение, в котором используется сетка пространств для отображения событий, таких как сообщения, предметы, квесты, враги и т.д.

Форма, над которой я сейчас работаю, создаст сетку с помощью кнопок, поскольку значения будут вводиться в поля ввода - это создает лучшее визуальное представление.

Я работаю над этой функцией, которая делает следующее.

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>";
        }

не дает абсолютно никакого поведения. Я не уверен, как двигаться дальше. Я был бы признателен за любые предложения по этому поводу.

Спасибо.

Теги:
for-loop
javascript-events
nested

1 ответ

1

Проблема здесь:

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
  • 0
    Это работало прекрасно. Спасибо за быстрый ответ также! Я понятия не имел об этом. Обязательно учту это на будущее! Еще раз спасибо!
  • 0
    @JonathanHinds Лучшим вариантом было бы обернуть кнопки в элемент уровня блока. <br/> В некоторых мнениях считается плохой практикой. Почему БР это плохо
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню