#javascript #arrays #dom
#javascript #массивы #dom
Вопрос:
Я создаю gem-головоломку. У меня есть кнопка сохранения, которая после нажатия на перезагрузку страницы показывает последнее сохраненное состояние игры. Но когда я перезагружаю страницу, таблица отображается, но событие перемещения щелчка не работает. Как это можно исправить? Какие новые аргументы необходимо передать функции moveThisTile? Или я должен сохранить что-то еще в localstorage? Чтобы объяснить мой код: функция startNewGame вызывается для создания пятнадцатой головоломки. showTable перебирает двумерный массив arrayForBoard и генерирует необходимый HTML-код для доски с пятнадцатью головоломками. moveThisTile принимает два аргумента, которые сообщают программе, какую плитку из пятнадцати головоломок нужно переместить
let moves = 0;
let table;
let rows;
let columns;
let textMoves;
let arrayForBoard;
let volumeOn = true;
function start() {
let button = document.getElementById('newGame');
button.addEventListener('click', startNewGame, false );
textMoves = document.getElementById('moves');
table = document.getElementById('table');
rows = 4;
columns = 4;
startNewGame();
}
function startNewGame() {
let arrayOfNumbers = new Array();
let arrayHasNumberBeenUsed;
let randomNumber = 0;
let count = 0;
moves = 0;
rows = document.getElementById('rows').value;
columns = document.getElementById('columns').value;
textMoves.innerHTML = moves;
arrayForBoard = new Array(rows);
for (let i = 0; i < rows; i ){
arrayForBoard[i] = new Array(columns);
}
arrayHasNumberBeenUsed = new Array( rows * columns );
for (let i = 0; i < rows * columns; i ){
arrayHasNumberBeenUsed[i] = 0;
}
for (let i = 0; i < rows * columns; i ){
randomNumber = Math.floor(Math.random()*rows * columns);
if (arrayHasNumberBeenUsed[randomNumber] == 0) {
arrayHasNumberBeenUsed[randomNumber] = 1;
arrayOfNumbers.push(randomNumber);
}else {
i--;
}
}
count = 0;
for (let i = 0; i < rows; i ){
for (let j = 0; j < columns; j ){
arrayForBoard[i][j] = arrayOfNumbers[count];
count ;
}
}
showTable();
}
let tbody = document.createElement('tbody');
document.querySelector('#table').appendChild(tbody);
function showTable() {
for (let tr of document.querySelectorAll("#table tr")) {
tr.remove();
}
for (let i = 0; i < rows; i ) {
let tr = document.createElement('tr');
for (let j = 0; j < columns; j ) {
let cell = document.createElement('td');
if (arrayForBoard[i][j] == 0) {
cell.className = 'blank';
} else {
cell.className = 'tile';
cell.draggable = true;
cell.addEventListener('click', () => {
moveThisTile(i, j);
if(volumeOn) {
sound()
}
})
cell.innerHTML =arrayForBoard[i][j];
}
tr.appendChild(cell);
}
tbody.appendChild(tr);
}
};
function moveThisTile(tableRow, tableColumn) {
if (checkIfMoveable(tableRow, tableColumn, 'up') ||
checkIfMoveable(tableRow, tableColumn, 'down') ||
checkIfMoveable(tableRow, tableColumn, 'left') ||
checkIfMoveable(tableRow, tableColumn, 'right') ) {
incrementMoves();
} else {
alert('ERROR: Cannot move tile!nTile must be next to a blank space.');
}
if (checkIfWinner()) {
stopTimer();
alert(`Congratulations! You solved the puzzle in ${moves} moves and in ${document.querySelector('#timespan').innerText}.`);
startNewGame();
}
}
function checkIfMoveable(rowCoordinate, columnCoordinate, direction) {
let rowOffset = 0;
let columnOffset = 0;
if (direction == 'up') {
rowOffset = -1;
} else if (direction == 'down') {
rowOffset = 1;
} else if (direction == 'left') {
columnOffset = -1;
} else if (direction == 'right') {
columnOffset = 1;
}
if (rowCoordinate rowOffset >= 0 amp;amp; columnCoordinate columnOffset >= 0 amp;amp;
rowCoordinate rowOffset < rows amp;amp; columnCoordinate columnOffset < columns
) {
if ( arrayForBoard[rowCoordinate rowOffset][columnCoordinate columnOffset] == 0) {
arrayForBoard[rowCoordinate rowOffset][columnCoordinate columnOffset] = arrayForBoard[rowCoordinate][columnCoordinate];
arrayForBoard[rowCoordinate][columnCoordinate] = 0;
showTable();
return true;
}
}
return false;
}
document.querySelector('.save-btn').addEventListener('click', () => {
localStorage.setItem('currentGame', document.querySelector('tbody').innerHTML);
localStorage.setItem('currentMoves', document.querySelector('#moves').innerHTML);
localStorage.setItem('currentTime', document.querySelector('#timespan').innerHTML);
})
window.addEventListener('load', () => {
if(localStorage.getItem('currentGame') !== null) {
tbody.innerHTML = localStorage.getItem('currentGame');
document.querySelector('#moves').innerHTML = localStorage.getItem('currentMoves');
document.querySelector('#timespan').innerHTML = localStorage.getItem('currentTime');
} else {
start();
}
}, false );
Комментарии:
1. Вы заменяете элементы внутри
tbody
, поэтому вам нужно переназначить прослушиватель кликов для каждого нового <td> . Вместо этого вы должны сохранить / загрузить массив, а затем обновить каждый<td>
.innerText
из них, таким образом, вы не потеряете обработчики событий (и не имеете HTML, который полностью не синхронизирован с вашим массивом)2. @ChrisG итак, я должен написать localStorage.setItem(‘currentGame’, arrayForBoard[i] [j])?
3. Нет,
localStorage.setItem('currentGame', JSON.stringify(arrayForBoard))
, поскольку вы хотите сохранить весь массив, а не только один элемент на основе неопределенных индексов (иarrayForBoard = JSON.parse(localStorage.getItem('currentGame'))
для загрузки)4. @ChrisG если я напишу в window.addEventListener(‘load’, () => {if(localStorage.GetItem(‘currentGame’)!== null){JSON.parse(localStorage.GetItem(‘currentGame’))}} таблица в HTML будет пустой после перезагрузкистраница
5. При условии, что вы сохранили там массив, вам нужно
arrayForBoard = JSON.parse(localStorage.getItem('currentGame'))
(как я уже говорил в моем предыдущем комментарии); затем вам нужно фактически заполнить таблицу: выполнить итерацию по вашему массиву и поместить значения в соответствующие<td>
.