Програмування html-таблиць розглядається на прикладі створення гри П'ятнашки. Для цієї гри потрібна 4 × 4-таблиця.
Наведений далі код дозволяє:
- створювати довільну n × n -таблиця;
- виконувати її початкове заповнення;
- переміщати ігрову кістка (цифру) в вільну комірку таблиці.
Також підтримуються різні види курсорів миші (pointer, crosshair і default, [1]) і інший необхідний для гри функціонал.
tbl = "";
mT = 0;
function mkTbl (tdSz, n) mT = n;
td = "
tHdr = "
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
>
>
Зауваження. Надалі для додання курсору миші належного вигляду буде вжито наступний код:
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
>
kL = kL2 = 0;
// Цикл заповнення масиву arrF
// Число ітерацій не більше 10000
while (kL
if (k> 0 arrF2 [k - 1]) arrF2 [k - 1] = false;
arrF [kL] = k;
kL ++;
>
>
kL = 0;
// Цикл заповнення таблиці числами з масиву arrF
for (i = 0; i
>
>
>
Зауваження. Натомість 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 = "
tHdr = "
>
function sayRC (cll) // Номер стовпця поточної комірки
c = cll.cellIndex;
r = gtRw (cll, c);
alert ( "Осередок" + r + ":" + c);
>
// Повертає номер рядка, якій розташована осередок cll
function gtRw (cll, c) for (i = 0; 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
>
kL = kL2 = 0;
// Цикл заповнення масиву arrF
// Число ітерацій не більше 10000
while (kL
if (k> 0 arrF2 [k - 1]) arrF2 [k - 1] = false;
arrF [kL] = k;
kL ++;
>
>
kL = 0;
// Цикл заповнення таблиці числами з масиву arrF
for (i = 0; i
>
>
>
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
>
>
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
>
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]):