как применить функцию к созданной таблице из localstorage

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