js бегущая строка, которую не предполагается использовать в if в для

#javascript

#javascript

Вопрос:

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

Html — это таблица с пустым tbody.

Css:

 table{
   border-collapse:collapse;
   background-color:black;
}
td{
   width:47.5px;
   height47.5px;
   padding:0px;
   border:2.5px solid gray;
}
td.live{
   background-color:white;
}
  

js:

             const size={
                x:5,
                y:5
            };
            var matrix=[];
            for(var i=[0, 0], rows=[]; i[0]<size.y; i[0]  ){
                rows.push(document.createElement("tr"));
                document.querySelector("tbody").appendChild(rows[i[0]]);
                matrix.push([]);
                for(i[1]=0; i[1]<size.x; i[1]  ){
                    matrix[i[0]][i[1]]=document.createElement("td");
                    matrix[i[0]][i[1]].setAttribute("x", i[1]);
                    matrix[i[0]][i[1]].setAttribute("y", i[0])
                    rows[i[0]].appendChild(matrix[i[0]][i[1]]);
                }
            }
            for(var i=[0,0]; i[0]<matrix.length; i[0]  ){
                for(i[1]=0; i[1]<matrix[0].length; i[1]  ){
                    matrix[i[0]][i[1]].onclick=function(){
                        this.classList.toggle("live");
                    }
                }
            }
            var interval=setInterval(loop(), 500);
            function loop(){
                for(var i=[0,0]; i[0]<matrix.length; i[0]  ){
                    for(i[1]=0; i[1]<matrix[0].length; i[1]  ){
                        const x=Number(matrix[i[0]][i[1]].getAttribute("x"));
                        const y=Number(matrix[i[0]][i[1]].getAttribute("y"));
                        var liveNeighbors=0;
                        if(x!=size.x){
                            if(document.querySelector('td[x="' (x 1) '"]').classList.contains("live")){
                                liveNeighbors  ;
                            }
                        }
                        if(y!=size.y){
                            if(document.querySelector('td[y="' (y 1) '"]').classList.contains("live")){
                                liveNeighbors  ;
                            }
                        }
                        if(x!=0){
                            if(document.querySelector('td[x="' (x-1) '"]').classList.contains("live")){
                                liveNeighbors  ;
                            }
                        }
                        if(y!=0){
                            if(document.querySelector('td[y="' (y-1) '"]').classList.contains("live")){
                                liveNeighbors  ;
                            }
                        }
                        if(!(matrix[i[0]][i[1]].classList.contains("live"))amp;amp;liveNeighbors==3){
                            matrix[i[0]][i[1]].classList.add("live");
                        }
                        if(matrix[i[0]][i[1]].classList.contains("live")amp;amp;(liveNeighbors!=2||liveNeighbors!=3)){
                            matrix[i[0]][i[1]].classList.remove("live");
                        }
                    }
                }
            }
  

Это ошибка:

* Неперехваченная ошибка типа: не удается прочитать свойство ‘classList’ с нулевым значением в цикле *

Я думаю, что он запускает код в циклах if, когда этого не должно быть.

Заранее спасибо! (:

Комментарии:

1. с помощью этого селектора запросов не получается один уникальный элемент проверьте, есть ли у вас несколько совпадений, затем назначьте их правильно document.querySelector('td[y="' (y 1) '"]')[i].classList

2. Документ. Метод querySelecotor() возвращает только 1 элемент, документ. Метод querySelectorAll() выполняет.

3. Попробуйте добавить полный фрагмент с помощью HTML

Ответ №1:

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

Элемент таблицы имеет rows свойство, которое возвращает коллекцию своих строк, которая не может быть проиндексирована. В таблице также есть метод insertRow()

Строка таблицы имеет cells свойство, которое также может быть проиндексировано, и у нее есть метод insertCell()

Следующее немного грубо и не содержит ошибок в отношении текущего количества, но должно дать вам хорошее представление о том, как это сделать без необходимости использования querySelector() и как перебирать все строки и ячейки

 const size = { x: 5, y:5};
const table = document.querySelector('table');

buildRows()
setInterval(loop, 2000);



function getLiveCount(cell){
   const {x, y} = cell.dataset;
   const rows = table.rows;
   const left = rows[y].cells[x-1],
         right = rows[y].cells[x 1],
         above = rows[y-1] amp;amp; rows[y-1].cells[x],
         below = rows[y 1] amp;amp; rows[y 1].cells[x];
   return [left, right, above, below].filter(cell=>cell)
          .reduce((a, currCell)=> a   currCell.matches('.live'),0)      
}

function loop(){ 
   [...table.rows].forEach((row, i)=> {    
      [...row.cells].forEach(cell=> cell.textContent = getLiveCount(cell))      
   });
}

function buildRow(y) {
   const row = table.insertRow();
   for(let i=0; i <size.x; i  ){
      const cell = row.insertCell();
      Object.assign(cell.dataset, {x:i, y});
      cell.addEventListener('click',cellClick);      
   }  
}

function buildRows(){
   for(let i =0; i< size.y; i  ){
       buildRow(i)
   }
}


function cellClick(event){
   this.classList.toggle('live')
   console.log('x:', this.dataset.x, ' y:', this.dataset.y)
}  
 td {
  width: 20px;
  height: 20px;
  border: 1px solid #ccc
}

td.live {
  background: yellow
}  
 <table>
  <tbody></tbody>
</table>