#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>