Таблиці на javascript

Програмування html-таблиць розглядається на прикладі створення гри П'ятнашки. Для цієї гри потрібна 4 × 4-таблиця.
Наведений далі код дозволяє:

  • створювати довільну n × n -таблиця;
  • виконувати її початкове заповнення;
  • переміщати ігрову кістка (цифру) в вільну комірку таблиці.

Також підтримуються різні види курсорів миші (pointer, crosshair і default, [1]) і інший необхідний для гри функціонал.

tbl = "";
mT = 0;
function mkTbl (tdSz, n) mT = n;
td = " td + = ">";
tHdr = "

document.write (tHdr);
for (i = 0; i ");
for (j = 0; j >
document.write ( "");
>
document.write ( "
");
tbl = document.getElementById ( "tbl");
>
function sayRC (cll) // Номер стовпця поточної комірки
c = cll.cellIndex;
r = gtRw (cll, c);
alert ( "Осередок" + r + ":" + c);
>
// Повертає номер рядка, якій розташована осередок cll
function gtRw (cll, c) for (i = 0; i if (rw.cells [c] == cll) return i;
>
>

Зауваження. Надалі для додання курсору миші належного вигляду буде вжито наступний код:

tbl.style.cursor = 'pointer' // Або інший вид, наприклад crosshair

Запишемо наведений код в файл tryTbl.js і побудуємо html-таблицю, відкривши в браузері файл tst.html, що має таке наповнення:

Обидва файли (tryTbl.js і tst.html) знаходяться в одній папці.
Одержуваний після відкриття оглядачем файлу tst.html результат можна спостерігати на рис. 1.

Мал. 1. Таблиця з курсором pointer

Після удару мишею по комірці таблиці з'явиться наступне повідомлення (рис. 2):

Мал. 2. Обрана третій осередок у другому рядку таблиці (cellIndex = 2, rowIndex = 1)

У грі П'ятнашки все, крім однієї, елементи таблиці спочатку випадковим чином заповнюються цифрами від 1 до n × n - 1, де n - розмір заповнюється таблиці.
Цю дію можна виконати за допомогою наступного коду.

function nGmFftngs () // mT - розмір заповнюється таблиці
fL = mT * mT;
// Масив генеруються цілих чисел
arrF = new Array (fL);
// Масив прапорців генеруються цілих чисел
// Елемент arrF2 [k] дорівнює false, якщо число k вже є в масиві arrF
arrF2 = new Array (fL);
for (k = 0; k arrF2 [k] = true;
>
kL = kL2 = 0;
// Цикл заповнення масиву arrF
// Число ітерацій не більше 10000
while (kL k = Math.floor (Math.random () * (fL + 1));
if (k> 0 arrF2 [k - 1]) arrF2 [k - 1] = false;
arrF [kL] = k;
kL ++;
>
>
kL = 0;
// Цикл заповнення таблиці числами з масиву arrF
for (i = 0; i for (j = 0; j rw.cells [j] .innerHTML = (k> fL - 1). "". k;
>
>
>

Зауваження. Натомість innerHTML можна вжити innerText

rw.cells [j] .innerText = (k> fL - 1). "". k;

Помістимо цей код в уже існуючий файл tryTbl.js. Пробний виклик функції забезпечить виконання оглядачем модифікованого файлу tst.html:

У порівнянні з первісним варіантом в поточному варіанті файлу tst.html додані визначення стилю тексту елементи таблиці і виклик функції nGmFftngs, що заповнює таблицю. Результат наведено на рис. 3.

Мал. 3. Випадкове заповнення 5 × 5-таблиці

Цифра, що сусідить з порожньою осередком по горизонталі або вертикалі, може бути переміщена в цей осередок. Так, в ситуації, наведеної на рис. 3, в порожню клітинку можна перемістити цифру 3, 11, 14 або 15.
У наведеній програмі курсор миші, якщо він розташований над цифрою сусідом, має вигляд pointer, в іншому випадку курсор відображається як crosshair. Така поведінка забезпечує обробник mkCrsr події mouseover, що виникає при позиціонуванні миші на елементі таблиці.

Цей оброблювач задається в модифікованої функції mkTbl створення таблиці. У цій функції рядок коду

замінюється на наступний рядок:

Сам же обробник задається наступними функціями (обидві функції поміщені в файл tryTbl.js):

function mkCrsr (cll) c = cll.cellIndex;
r = gtRw (cll, c);
if (r == -1)
mvd = false;
else
for (kL = 0; kL <4; kL++) switch (kL) case 0. mvd = chkC2(r - 1, c, cll); break;
case 1. mvd = chkC2 (r, c - 1, cll); break;
case 2. mvd = chkC2 (r + 1, c, cll); break;
case 3. mvd = chkC2 (r, c + 1, cll); break;
>
if (mvd) break;
>
tbl.style.cursor = (mvd). 'Pointer'. 'Crosshair';
>
// Повертає true, якщо осередок r2: c2 є порожній
function chkC2 (r2, c2, cll) if (r2 == -1 || c2 == -1 || r2 == mT || c2 == mT) return false;
cll2 = tbl.rows [r2] .cells [c2];
if (cll2.innerHTML == "") return true;
>

Обидві форми курсору можна спостерігати на рис. 4.

Мал. 4. Над цифрою 3 курсор має вигляд pointer, а над цифрою 2 - crosshair

Зауваження. Курсор, якщо він розташований поза таблиці, має вигляд default.

Перевірка обробника виконується в результаті відкриття файлу tst.html.

Цифра, що сусідить по горизонталі або вертикалі з порожньою осередком, займає цей осередок за допомогою обробника mvFg події click, що виникає після удару мишею по цифрі. Звільняється осередок стає порожній (рис. 5).

Мал. 5. Переміщення цифри 7 оброблювачем mvFg події click

Цей оброблювач задається в модифікованої функції mkTbl створення таблиці. У цій функції рядок коду

замінюється на наступний рядок:

Оброблювач реалізується наступними функціями (обидві функції поміщені в файл tryTbl.js):

function mvFg (cll) c = cll.cellIndex;
r = gtRw (cll, c);
if (r == -1) return;
fL = mT * mT;
for (kL = 0; kL <4; kL++) switch (kL) case 0. mvd = chkC(r - 1, c, cll); break;
case 1. mvd = chkC (r, c - 1, cll); break;
case 2. mvd = chkC (r + 1, c, cll); break;
case 3. mvd = chkC (r, c + 1, cll); break;
>
>
>
function chkC (r2, c2, cll) if (r2 == -1 || c2 == -1 || r2 == mT || c2 == mT) return false;
cll2 = tbl.rows [r2] .cells [c2];
if (cll2.innerHTML == "") cll2.innerHTML = cll.innerHTML;
cll.innerHTML = "";
tbl.style.cursor = 'crosshair';
return true;
>
>

Перевірка обробника виконується в результаті відкриття файлу tst.html.

  • фіксацію моменту завершення гри (глобальна змінна dn приймає в цей момент значення true);
  • підрахунок ігрового часу (зберігає глобальна змінна tmS);
  • підрахунок числа ходів (зберігає глобальна змінна nFftngs);
  • завершення гри (функція bldFftngs);
  • відображення витрачених числа ходів і часу (функція sRslt).

// Глобальні змінні
tbl = "";
mT = 0;
dn = false;
tmS = 0;
nFftngs = 0;
//
function mkTbl (tdSz, n) mT = n;
td = " td + = ">";
tHdr = "

document.write (tHdr);
for (i = 0; i ");
for (j = 0; j >
document.write ( "");
>
document.write ( "
");
>
function sayRC (cll) // Номер стовпця поточної комірки
c = cll.cellIndex;
r = gtRw (cll, c);
alert ( "Осередок" + r + ":" + c);
>
// Повертає номер рядка, якій розташована осередок cll
function gtRw (cll, c) for (i = 0; i if (rw.cells [c] == cll) return i;
>
>
function nGmFftngs () dn = false;
nFftngs = 0;
dt = new Date ();
tmS = dt.getTime ();
// mT - розмір заповнюється таблиці
fL = mT * mT;
// Масив генеруються цілих чисел
arrF = new Array (fL);
// Масив прапорців генеруються цілих чисел
// Елемент arrF2 [k] дорівнює false, якщо число k вже є в масиві arrF
arrF2 = new Array (fL);
for (k = 0; k arrF2 [k] = true;
>
kL = kL2 = 0;
// Цикл заповнення масиву arrF
// Число ітерацій не більше 10000
while (kL k = Math.floor (Math.random () * (fL + 1));
if (k> 0 arrF2 [k - 1]) arrF2 [k - 1] = false;
arrF [kL] = k;
kL ++;
>
>
kL = 0;
// Цикл заповнення таблиці числами з масиву arrF
for (i = 0; i for (j = 0; j rw.cells [j] .innerHTML = (k> fL - 1). "". k;
>
>
>
function mkCrsr (cll) if (dn) mvd = false;
else c = cll.cellIndex;
r = gtRw (cll, c);
if (r == -1)
mvd = false;
else
for (kL = 0; kL <4; kL++) switch (kL) case 0. mvd = chkC2(r - 1, c, cll); break;
case 1. mvd = chkC2 (r, c - 1, cll); break;
case 2. mvd = chkC2 (r + 1, c, cll); break;
case 3. mvd = chkC2 (r, c + 1, cll); break;
>
if (mvd) break;
>
>
tbl.style.cursor = (mvd). 'Pointer'. 'Crosshair';
>
// Повертає true, якщо осередок r2: c2 є порожній
function chkC2 (r2, c2, cll) if (r2 == -1 || c2 == -1 || r2 == mT || c2 == mT) return false;
cll2 = tbl.rows [r2] .cells [c2];
if (cll2.innerHTML == "") return true;
>
function mvFg (cll) if (dn) return;
c = cll.cellIndex;
r = gtRw (cll, c);
if (r == -1) return;
fL = mT * mT;
for (kL = 0; kL <4; kL++) switch (kL) case 0. mvd = chkC(r - 1, c, cll); break;
case 1. mvd = chkC (r, c - 1, cll); break;
case 2. mvd = chkC (r + 1, c, cll); break;
case 3. mvd = chkC (r, c + 1, cll); break;
>
// Перевіряємо, завершена гра чи ні
if (mvd) // Змінна dn буде дорівнює true, якщо гра завершена
dn = true;
k = 0;
for (i = 0; i for (j = 0; j if (k break;
>
>
if (! dn) break;
>
if (dn) sRslt ();
break;
>
>
>
function chkC (r2, c2, cll) if (r2 == -1 || c2 == -1 || r2 == mT || c2 == mT) return false;
cll2 = tbl.rows [r2] .cells [c2];
if (cll2.innerHTML == "") nFftngs ++;
cll2.innerHTML = cll.innerHTML;
cll.innerHTML = "";
tbl.style.cursor = 'crosshair';
return true;
>
>
// Вибудовує кістки в належному порядку
function bldFftngs () if (dn) return;
k = 0;
for (i = 0; i for (j = 0; j 15). "". k;
>
dn = true;
sRslt ();
>
// Показує витрачені час і число ходів
function sRslt () dt = new Date ();
tm = Math.round (0.001 * (dt.getTime () - tmS));
alert ( "Гра завершена. Число ходів" + nFftngs + ". Витрачено часу" + tm + "с.");
>

Перехід до гри здійснюється в результаті відкриття файлу fftngs.html, що відтворює опис гри (рис. 6), її ініціалізацію і завершення.

Мал. 6. У браузері відкритий файл fftngs.html

Файл fftngs.html містить наступний код:

Після завершення гри функція sRslt забезпечить наведене на рис. 7 повідомлення.

Мал. 7. Гру закінчено

Html-таблиця є досить складним об'єктом. Зокрема, її осередок (HTMLElement td) має наступні події, методи і властивості (їх детальний опис можна знайти в [2]):

Схожі статті