Uncaught TypeError — Неожиданное поведение

var chanceOfLiveCells = 0.5;
var gridDomReference = null;
var gridDimension = 15;
var timer = null;

function init() {

    gridDomReference = document.getElementById('grid');
    idleCells = new Array();
    liveCells = new Array();
    deadCells = new Array();

    drawGrid();
    createRandomLiveCells();

}

function drawGrid() {

    var counter = 0;
    var nodes = new Array();

    for(var x = 0; x <= gridDimension - 1; x = x + 1) {

        nodes.push('<tr>');

        for(var y = 0; y <= gridDimension - 1; y = y + 1) {

            nodes.push('<td id="' + counter + '">' + counter + '</td>');
            idleCells.push(counter);
            counter = counter + 1;

        }

        nodes.push('</tr>');

    }

    gridDomReference.innerHTML = nodes.join('');

}

function createRandomLiveCells() {

    for(var x = 0; x <= gridDimension - 1; x = x + 1) {

        for(var y = 0; y <= gridDimension - 1; y = y + 1) {

            if(Math.random() < chanceOfLiveCells) {

                liveCells.push(x * gridDimension + y);
                idleCells.splice(getCell('idle', x, y), 1);
                document.getElementById(getCell('live', x, y)).innerHTML = 'L';
                console.log('[Live function] Live cells: ' + liveCells.length + ' | ' + ' Dead cells: ' + deadCells.length
                        + ' | Idle cells: ' + idleCells.length + ' | ' + 'getCell: ' + getCell('live', x, y) 
                        + ' | N: ' + (x * gridDimension + y));

            }

            else {

                deadCells.push(x * gridDimension + y);
                idleCells.splice(getCell('idle', x, y), 1);
                document.getElementById(getCell('dead', x, y)).innerHTML = 'D';
                console.log('[Dead function] Dead cells: ' + deadCells.length + ' | ' + ' Live cells: ' + liveCells.length
                        + ' | Idle cells: ' + idleCells.length + ' | ' + 'getCell: ' + getCell('dead', x, y) 
                        + ' | N: ' + (x * gridDimension + y));

            }

        }

    }

}

function getCell(array, x, y) {

    if(x > gridDimension - 1) {

        x = 0;

    }

    if(y > gridDimension - 1) {

        y = 0;

    }

    if(x < 0) {

        x = gridDimension - 1;

    }

    if(y < 0) {

        y = gridDimension - 1;

    }

    switch(array) {

        case 'idle': 

            return idleCells[x * gridDimension + y]; 

        break;

        case 'live': 

            return liveCells[x * gridDimension + y]; 

        break;

        case 'dead': 

            return deadCells[x * gridDimension + y]; 

        break;

    }

}

Я нахожусь в процессе переписывания своей реализации игры Конвея «Жизнь», но до этого переписывания я столкнулся с несколькими проблемами. Я предполагаю, что мой код правильный, но я сбит с толку этой проблемой. Я провел некоторое исследование по этому поводу, и многие люди говорят, что это связано с тем, как Chrome «делает что-то».

Вот общий вывод в консоли от выполнения:

gameoflife.js:54 [Живая функция] Живые ячейки: 1 | Мертвые клетки: 0 | Свободных ячеек: 225 | получить ячейку: 0 | N: 0 gameoflife.js: 54 [Живая функция] Живые ячейки: 2 | Мертвые клетки: 0 | Свободные ячейки: 224 | получить ячейку: 1 | N: 1 gameoflife.js: 54 [Живая функция] Живые ячейки: 3 | Мертвые клетки: 0 | Свободные ячейки: 221 | получить ячейку: 2 | N: 2 gameoflife.js: 54 [Живая функция] Живые ячейки: 4 | Мертвые клетки: 0 | Свободные ячейки: 214 | получить ячейку: 3 | N: 3 gameoflife.js: 54 [Живая функция] Живые ячейки: 5 | Мертвые клетки: 0 | Свободные ячейки: 206 | получить ячейку: 4 | N: 4 gameoflife.js: 54 [Живая функция] Живые ячейки: 6 | Мертвые клетки: 0 | Свободные ячейки: 197 | получить ячейку: 5 | N: 5 gameoflife.js: 54 [Живая функция] Живые ячейки: 7 | Мертвые клетки: 0 | Свободные ячейки: 187 | получить ячейку: 6 | N: 6 gameoflife.js: 54 [Живая функция] Живые ячейки: 8 | Мертвые клетки: 0 | Свободные ячейки: 169 | получить ячейку: 7 | N: 7 gameoflife.js: 54 [Живая функция] Живые ячейки: 9 | Мертвые клетки: 0 | Свободные ячейки: 142 | получить ячейку: 8 | N: 8 gameoflife.js: 54 [Живая функция] Живые ячейки: 10 | Мертвые клетки: 0 | Свободные ячейки: 105 | получить ячейку: 9 | N: 9 gameoflife.js: 64 Uncaught TypeError: невозможно установить для свойства 'innerHTML' значение null

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

gameoflife:62 [Мертвая функция] Мертвые клетки: 0 | Живые клетки: 5 | Свободные ячейки: 206 | getCell: не определено | N: 5 gameoflife.js: 47 Uncaught TypeError: невозможно установить для свойства 'innerHTML' значение null

Учитывая, что нет никакой разницы с созданием живых клеток, я не уверен, почему это происходит. Но вот еще одна вещь, которая сбивает с толку: с меньшей вероятностью живых клеток функция, которая создает мертвые клетки, действительно работает, и тогда проблема заключается в функции, которая создает живые клетки. Мало того, существует странная закономерность в количестве ячеек в массиве idleCells, учитывая, что я использую функцию splice() только один раз на каждой итерации для удаления индекса, который находится либо в массиве liveCells, либо в массиве deadCells.

Сначала создается сетка, а затем в idleCells заносятся идентификаторы ячеек таблицы. Когда я вызываю функцию createRandomLiveCells(), работа этой функции заключается в создании случайных ячеек, мертвых или живых. Таким образом, я ожидаю, что и массив liveCells, и массив deadCells составляют количество ячеек таблицы, а массив idleCells пуст, поскольку свободных ячеек нет, потому что ячейки таблицы либо мертвы, либо живы.

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

Спасибо за чтение этой длинной, но, надеюсь, хорошо объясненной проблемы и за вашу помощь.


person Mark    schedule 16.05.2011    source источник


Ответы (1)


Прежде всего, document.getElementById(str) ожидает строку, а не число, как в вашем случае.

И второе, значение атрибута ID в html должно соответствовать правилам, изложенным здесь: http://www.w3.org/TR/html40/struct/global.html#h-7.5.2

Особенно:

Токены ID и NAME должны начинаться с буквы ([A-Za-z]), за ними может следовать любое количество букв, цифр ([0-9]), дефисов («-»), подчеркиваний («_») , двоеточия (":") и точки (".").

Обратите внимание, что идентификатор должен начинаться с буквы. Но вы используете простые цифры.

person c-smile    schedule 16.05.2011
comment
Ну, я не вижу проблем с тем, как я использую getElementById(), так как он выполняет успешные манипуляции с таблицей в HTML... Я добавлю 'C' к идентификатору вместе со значением счетчика. - person Mark; 16.05.2011
comment
Изменение кода на то, что я сказал выше, создает большую проблему. Так что да, я не вижу проблем с тем, как я использую getElementById()... - person Mark; 16.05.2011