Ввод кроссворда в JavaScript зависает, и фокус не перемещается на следующую ячейкуJavascript

Форум по Javascript
Ответить
Anonymous
 Ввод кроссворда в JavaScript зависает, и фокус не перемещается на следующую ячейку

Сообщение Anonymous »

Проблема
  • Когда я ввожу букву в ячейку, фокус не перемещается на следующую ячейку в слове.
  • После ввода буквы вся система ввода перестает отвечать — я не могу вводить больше букв, удалять их или нажимать на другие ячейки.
  • Ощущение, будто обработчик событий выдает ошибку и прекращает дальнейшее выполнение.
Думаю, все проблемы в renderGrid(), но я не знаю, где именно они.
(у меня все html-элементы написаны правильно)

Код: Выделить всё

const GRID_ROWS = 10;
const GRID_COLS = 10;
const WORDS = [
// Across
{ word: 'READ', clue: 'To look at and comprehend written words', row: 0, col: 0, direction: 'across', id: 1 },
{ word: 'EASY', clue: 'Not difficult', row: 2, col: 2, direction: 'across', id: 2 },
{ word: 'NOTE', clue: 'A short written message', row: 4, col: 4, direction: 'across', id: 3 },
{ word: 'GAME', clue: 'An activity for fun or competition', row: 6, col: 6, direction: 'across', id: 4 },
// Down
{ word: 'RENT', clue: 'To pay for the use of something', row: 0, col: 0, direction: 'down', id: 5 },
{ word: 'DEAN', clue: 'A college official', row: 0, col: 2, direction: 'down', id: 6 },
{ word: 'SONG', clue: 'A musical composition', row: 2, col: 4, direction: 'down', id: 7 },
{ word: 'MEGA', clue: 'Very large', row: 4, col: 6, direction: 'down', id: 8 },
];

let grid = [];
let selectedWordId = null;
let completedWords = new Set();

function createGrid() {
grid = Array.from({ length: GRID_ROWS }, (_, r) =>
Array.from({ length: GRID_COLS }, (_, c) => ({
row: r,
col: c,
letter: null,
value: '',
words: []
}))
);
WORDS.forEach(wordObj => {
let r = wordObj.row, c = wordObj.col;
for (let i = 0; i < wordObj.word.length; i++) {
const cell = grid[r][c];
cell.letter = wordObj.word[i];
cell.words.push(wordObj.id);
if (wordObj.direction === 'across') c++;
else r++;
}
});
}

function renderGrid() {
const table = document.getElementById('crosswordGrid');
table.innerHTML = '';
for (let r = 0; r < GRID_ROWS; r++) {
const tr = document.createElement('tr');
for (let c = 0; c < GRID_COLS; c++) {
const cell = grid[r][c];
const td = document.createElement('td');
if (cell.letter) {
const input = document.createElement('input');
input.type = 'text';
input.maxLength = 1;
input.className = 'crossword-cell';
input.value = cell.value;
input.dataset.row = r;
input.dataset.col = c;
input.onfocus = () => selectCell(r, c);
input.oninput = e => handleInput(e, r, c);
td.appendChild(input);
} else {
td.className = 'cell-blocked';
}
tr.appendChild(td);
}
table.appendChild(tr);
}
}

function renderClues() {
const acrossDiv = document.getElementById('acrossClues');
const downDiv = document.getElementById('downClues');
acrossDiv.innerHTML = '';
downDiv.innerHTML = '';
WORDS.forEach(word => {
const clueDiv = document.createElement('div');
clueDiv.className = 'clue' + (selectedWordId === word.id ? ' selected' : '') + (completedWords.has(word.id) ? ' completed' : '');
clueDiv.textContent = word.clue;
clueDiv.onclick = () => selectWord(word.id);
if (word.direction === 'across') acrossDiv.appendChild(clueDiv);
else downDiv.appendChild(clueDiv);
});
}

function selectWord(wordId) {
selectedWordId = wordId;
renderClues();
// Focus first cell of the word
const word = WORDS.find(w =>  w.id === wordId);
if (word) {
const input = document.querySelector(`input[data-row="${word.row}"][data-col="${word.col}"]`);
if (input) input.focus();
}
}

function selectCell(row, col) {
// Select the first word that uses this cell
const cell = grid[row][col];
if (cell.words.length) {
selectWord(cell.words[0]);
}
}

function handleInput(e, row, col) {
const val = e.target.value.toUpperCase();
if (!val.match(/^[A-Z]?$/)) {
e.target.value = '';
return;
}
grid[row][col].value = val;
checkWordsAtCell(row, col);
renderClues();
updateScore();

if (val) {
let word = null;
if (selectedWordId) {
word = WORDS.find(w => w.id === selectedWordId);
} else {
// Если слово не выбрано, выбираем первое из возможных для клетки
const cell = grid[row][col];
if (cell.words.length) {
word = WORDS.find(w => w.id === cell.words[0]);
selectedWordId = cell.words[0];
renderClues();
}
}
if (word) {
let nextRow = row;
let nextCol = col;
if (word.direction === 'across') nextCol++;
else nextRow++;
// Проверяем, есть ли следующая клетка в слове
for (let i = 0; i < word.word.length; i++) {
const r = word.row + (word.direction === 'down' ? i : 0);
const c = word.col + (word.direction === 'across' ? i : 0);
if (r === nextRow && c === nextCol) {
const nextInput = document.querySelector(`input[data-row="${nextRow}"][data-col="${nextCol}"]`);
if (nextInput) nextInput.focus();
break;
}
}
}
}
}

function checkWordsAtCell(row, col) {
const cell = grid[row][col];
cell.words.forEach(wordId => {
const word = WORDS.find(w => w.id === wordId);
let r = word.row, c = word.col, correct = true;
for (let i = 0; i < word.word.length; i++) {
if (grid[r][c].value !== word.word[i]) {
correct = false;
break;
}
if (word.direction === 'across') c++;
else r++;
}
if (correct) completedWords.add(wordId);
});
}

function updateScore() {
document.getElementById('scoreDisplay').textContent = `Words Completed: ${completedWords.size}`;
}

function resetCrossword() {
completedWords.clear();
selectedWordId = null;
createGrid();
renderGrid();
renderClues();
updateScore();
}

window.onload = () => {
createGrid();
renderGrid();
renderClues();
updateScore();
};

Код: Выделить всё

#scoreDisplay, #crosswordGrid, #acrossClues, #downClues {
background: whitesmoke;
border: thin dashed lightgray;
margin: 0.5rem;
padding: 0.5rem;
}



Подробнее здесь: https://stackoverflow.com/questions/798 ... -next-cell
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»