Невозможно настроить таргетинг на созданную кнопку JS в массиве с функцией, возникает ошибка «Не удается прочитать свойство 'setAttribute' of null» - PullRequest
0 голосов
/ 12 июля 2020

Я просто пытаюсь изменить фон определенной c кнопки при нажатии на нее. Я сгенерировал 100 кнопок (в надежде сделать простую игру позже) в виде массива через a for l oop, назначив идентификатор и отдельный вызов функции (на основе увеличивающегося значения i для l oop), и я не могу фактически вызвать изменение фона после щелчка, вместо этого получаю следующую ошибку «Uncaught TypeError: невозможно прочитать свойство 'setAttribute' со значением null в showOptions (brain. js: 31) в HTMLButtonElement.onclick ( index. html: 15) "

Мой код выглядит следующим образом:

var btn = [];
function generateBoard() {
  for (i = 0; i < 100; i++) {
    var modulo = i % 10;
    var up, forLeft;
    btn[i] = document.createElement("BUTTON");
    var element = document.getElementById("body");
    //btn[i].innerText = "CLICK ME";
    element.appendChild(btn[i]);
    btn[i].style.backgroundColor = "white";
    btn[i].id = i;
    btn[i].style.width = "50px";
    btn[i].style.height = "40px";
    btn[i].style.position = "absolute";
    btn[i].style.top = modulo * 100;
    btn[i].style.left = Math.floor(i / 10) * 100;
    btn[i].x = (i + 10) % 10;
    btn[i].y = Math.floor(i / 10);
    document
      .getElementById(btn[i].id)
      .setAttribute("onclick", "showOptions(i)");
    btn[i].innerText = btn[i].id;

    console.log(
      btn[i].id +
        " " +
        btn[i].style.left +
        " " +
        btn[i].style.top +
        " " +
        btn[i].x +
        " " +
        btn[i].y
    );
  }
}
generateBoard();
function showOptions(i) {
  document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}

в console.log. Я получаю правильный di git как btn [i] .id, как ни странно.

строка (index. html: 15) ошибки просто

</html>

Ответы [ 3 ]

0 голосов
/ 12 июля 2020

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

var buttons = [];

function generateBoard(){
    for(i = 0; i < 100; i++) {
        var modulo = i % 10;
        buttons[i] = document.createElement("BUTTON");
        document.getElementById("body").appendChild(buttons[i]);
        //buttons[i].innerText = "CLICK ME";
        buttons[i].style.backgroundColor = "white";
        buttons[i].id = i;
        buttons[i].style.width = "50px";
        buttons[i].style.height = "40px";
        buttons[i].style.position = "absolute";
        buttons[i].style.top = modulo * 100;
        buttons[i].style.left = Math.floor(i / 10) * 100;
        buttons[i].x = (i + 10) % 10;
        buttons[i].y = Math.floor(i / 10);
        buttons[i].addEventListener('click', function(event) {
            // This code is run when the button is clicked
            // Note I am passing the element, rather than an id
            showOptions(this);
        });
        buttons[i].innerText = i;

        console.log(buttons[i].id + " " + buttons[i].style.left + " " + buttons[i].style.top + " " + buttons[i].x + " " + buttons[i].y);
    }
}
generateBoard();
function showOptions(button){
    button.style.backgroundColor = "red";
}
0 голосов
/ 12 июля 2020

Вместо того, чтобы назначать и пытаться использовать атрибут ID, вы можете настроить таргетинг на выбранный элемент, сославшись на свойство самого event. Если бы вы проанализировали event (используйте консоль), вы бы заметили несколько свойств - target разрешает доступ к самому элементу, что помогает упростить функцию showOptions. В этом случае вы также можете просто использовать this для ссылки на саму кнопку изнутри showOptions, что сделает его еще проще - например, this.style.backgroundColor='red';

let bttns=[];

const generateBoard=function( s=100 ){
  const showOptions=function(e){
    e.target.style.backgroundColor='red';
  };

  for( let i=0; i < s; i++ ){
    /* create a new button and add properties */
    let bttn=document.createElement('button');
      bttn.setAttribute('id',i);
      bttn.setAttribute('data-x',((i+10)%10));
      bttn.setAttribute('data-y',Math.floor(i/10));

      bttn.style.left=( Math.floor( i / 10 ) * 100 )+'px';
      bttn.style.top=( ( i % 10 ) * 100 )+'px';
      bttn.style.width = '50px';
      bttn.style.height = '40px';
      bttn.style.position = 'absolute';
      bttn.innerText=i;

      /* bind event listener */
      bttn.addEventListener('click', showOptions );

    /* add to the DOM */
    document.body.appendChild( bttn );

    /* if it is important to have in an array... */
    bttns.push( bttn );
  }
}

document.addEventListener('DOMContentLoaded',(e)=>{
  generateBoard( 100 );
})

Добавление произвольных атрибутов к элементам - не лучшая практика - вместо назначения x и y вам следует использовать атрибуты dataset, поэтому data-x и data-y будет правильным.

0 голосов
/ 12 июля 2020

Есть несколько проблем с вашим кодом. У вас должен получиться элемент body с getElementsByTagName, который возвращает массив. Так что выберите первый элемент. При настройке атрибута onclick следует использовать значение i, а не текст i.

var btn = [];

function generateBoard() {
  for (i = 0; i < 100; i++) {
    var modulo = i % 10;
    var up, forLeft;
    btn[i] = document.createElement("BUTTON");
    var element = document.getElementsByTagName("body")[0];
    //btn[i].innerText = "CLICK ME"; 
    element.appendChild(btn[i]);
    btn[i].style.backgroundColor = "white";
    btn[i].id = i;
    btn[i].style.width = "50px";
    btn[i].style.height = "40px";
    btn[i].style.position = "absolute";
    btn[i].style.top = modulo * 100;
    btn[i].style.left = Math.floor(i / 10) * 100;
    btn[i].x = (i + 10) % 10;
    btn[i].y = Math.floor(i / 10);
    
    document.getElementById(btn[i].id).setAttribute('onclick', 'showOptions(' + i + ')');
    btn[i].innerText = btn[i].id;


    console.log(btn[i].id + " " + btn[i].style.left + " " + btn[i].style.top + " " + btn[i].x + " " + btn[i].y);

  }
}
generateBoard();

function showOptions(i) {

  document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...