0  На главную

0 1.Как создают веб-страницы
Как написать веб-страницу
Обзор программ для просмотра
и создания веб-страниц
Создание веб-страниц

0 2.Основные средства языка HTML
Самое главное на любой веб-странице - гиперссылки
Как создать списки на веб-странице
Создание таблиц

0 3.Графика на веб-странице
Графические форматы
интернета
Графические элементы оформления
веб-страниц
Графические маркеры
Подготовка рисунков в
программе Adobe Photoshop

0 4.Оформление веб-страницы с использованием стилей
Определение стилей в
специальной таблице
Обзор других возможностий
стилевых таблиц

0 5.Использование звука на
веб-странице
Маленькие хитрости

0 6.Динамические веб-страницы
на основе JavaScript
Как писать собственные функции
Динамическое изменение внешнего
вида страницы
Другие возможности языка
JavaScript

0 7.Веб-страницы, реагирующие
на действия пользователя
Страница, управляемая
при помощи мыши
Страница, управляемая
с клавиатуры
Динамическое отображение
текста веб-страницы
Динамическое изменение
графических элементов веб-страницы
Динамическое изменение таблиц
Самоизменяющиеся формы

0 8.Размещение элементов на веб-странице
с помощью таблиц
Управление расположением элементов
на веб-страницы
Динамическое позиционирование слоев

0 9.Дополнительные возможности формирования веб-страниц
Пример использования элемента управления Tabular Data

Динамическое изменение таблиц

В главе 6 мы создали таблицу умножения, минимальные и максимальные значения множителей которой запрашивалось при загрузке (см. рис. 6.5 и 6.6). Однако согласитесь, что появление четырех диалоговых окон подряд при загрузке страницы может отпугнуть пользователя. Давайте попробуем усовершенствовать эту страницу, а заодно рассмотрим методы динамического изменения содержимого таблиц.

Итак, каким же образом лучше всего «попросить» пользователя задать минимальные и максимальные значения множителей? Вполне изящное решение — четыре небольших текстовых поля, как бы «вмонтированные* в пояснительный текст (рис. 7.19). Как видите, сверху есть ненавязчивая надпись Первый множитель: от 2 до 9. При этом числа 2 и 9 находятся в текстовых полях, и пользователь может изменить эти значения. При изменении значений изменится, соответственно, и содержимое таблицы.

Особенности таблиц

На первый взгляд, решение этой проблемы почти не отличается от рассмотренного в Главе 6. Создадим текстовые поля, прочитаем и преобразуем их значения и подставим их в функцию для генерации таблицы.

Рис. 7.19. Пользователь может изменять диапазон множителей с помощью текстовых полей в верхней части страницы

Однако, если подумать, то в данном случае имеется очень важное отличие: мы должны иметь возможность генерировать таблицу не один раз, а много — при каждом изменении одного из текстовых полей. И если в прошлом примере мы просто вставили соответствующий сценарий между тегами <ТАВLЕ> и </TABLE>, то теперь такой номер не пройдет: функция должна вызываться из обработчика событий текстового поля. Что же делать, чтобы записать код между <TABLE> и <TАВLЕ>? Может быть, вместо метода document.write использовать свойство innerHTML элемента <TABLE>?

Можно и так, но это очень усложнит код. Вместо этого лучше воспользоваться методами insertRow и insertCell, которые вставляют в таблицу строки и ячейки, соответственно.

Однако все по порядку. Сначала создадим пояснительный текст с полями для ввода значений множителей:

<Н2>ТАБЛИЦА УМНОЖЕНИЯ</Н2>

Первый множитель: от <INPUT TYPE="text" NAME="min1" VALUE="2" SIZE="3" MAXLENGTH="3" onChange="newtable()"> до <INPUT TYPE="text" NAME="max1" VALUE="9" SIZE="3" MAXLENGTH="3" onChange="newtable()"><BR>

Второй множитель: от <INPUT TYPE="text" NAME="min2" VALUE="2" SIZE="3" MAXLENGTH="3" onChange="newtable()"> до <INPUT TYPE="text" NAME="max2" VALUE="10" SIZE="3" MAXLENGTH="3" onChange="newtable()">

Как видите, мы сразу помещаем в текстовые поля значения, задаваемые по умолчанию, то есть диапазон первого множителя от 2 до 9, а второго — от 2 до 10. В каждом текстовом поле имеется обработчик событий onChange, который реагирует на изменение значения поля. Таким образом, при каждом изменении значения одного из полей должна вызываться некая функция newtable(), которую мы еще не написали. Она должна стереть имеющуюся таблицу и сгенерировать новую.

Теперь напишем код самой таблицы:

<TABLE ID="tbl" BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols">

</TABLE>

Поскольку содержимое таблицы должно генерироваться «на ходу», оставим ее пока пустой. Чтобы иметь легкий доступ к таблице, мы дали ей уникальное имя tbl (с помощью атрибута ID=).

Генерация строк и ячеек таблицы

Теперь напишем функцию, которая бы генерировала эту таблицу. Если бы мы имели возможность вызывать ее прямо из «тела» таблицы, мы могли бы написать так:

var i,j;
for (i=2; i<=10; i++) {
document.write ("<TR>");
for (j=2; j<10; j++)
document.write
("<TD>"+j+"<SUP>"+i+"</SUP>="+Math.pow(j,i)+"</TD>");
document.write ("</TR>");
}

Собственно говоря, мы так и делали в предыдущей главе. Теперь же мы должны вместо написания тегов <TR> и </TR> создать строку таблицы:

tbl.insertRow(номер_строки);

а вместо генерации тегов <TD> и </TD> и текста между ними создать ячейку:

tbl.rows[номер_строки].insertCell(номер_ячейки);

и заполнить ее содержимым:

tbl.rows[номер_строки].cells[номер_ячейки].innerText= 'содержимое';

Кроме того, эта функция должна принимать четыре аргумента (минимальные и максимальные значения множителей). Обозначим эти значения а и b для первого множителя, а также end — для второго:

function writable(a,b,с,d) {

Помимо счетчиков цикла i и j объявим еще две вспомогательные переменные — одну для хранения временной ссылки на текущую строку или ячейку (назовем ее nr), а другую — для хранения номера текущей строки:

var i,j,nr,rnr;

Теперь начнем первый цикл:

for (i=c; i<=d; i+ + ) {

Вот здесь нужно немного подумать. Нам нужно создать строку. Хорошо бы было написать:

nr=tbl.insertRow(i) ;

Однако, если это сделать, то мы получим ошибку «недопустимый аргумент» (если только минимальное значение второго множителя с не равно 0). И действительно: ведь коллекция строк таблицы (в данном случае tbl.rows) представляет собой массив. А первый элемент массива всегда имеет номер 0. То есть, если в массиве еще нет строк, то метод insertRow может принять только аргумент 0. Если есть одна строка, то аргументом может быть О или 1 (от этого зависит положение новой строки в таблице), и т. д.

К счастью, мы по условию определили, что i вначале равно с, и, значит, i-c=0. Затем значение i будет увеличиваться, а разность (i-c), соответственно, принимать значения 1, 2 и т. д. Это как раз то, что нам нужно. Напишем так:

nr=tbl.insertRow(i-c) ;

Теперь получим значение индекса вновь созданной строки:

rnr=nr.rowlndex;

Вообще говоря, в данном случае оно всегда будет равно i-c, так что мы спокойно могли бы написать rnr = i - с или вообще обойтись без этой переменной. Однако запись rnr = nr.rowlndex гораздо нагляднее и заодно демонстрирует применение свойства rowlndex.

Теперь начнем внутренний цикл:

for (j=a; j<=b; j++) {

В нем мы вставим ячейку в строку с номером rnr:

nr=tbl.rows[rnr].insertCell(j-a);

А теперь можно заполнить ячейку содержимым. Чтобы поставить знак умножения, мы здесь не можем применить HTML-конструкцию &times;. Однако, взглянув в таблицу, выясним, что этот символ имеет десятичный код 215, или восьмеричный 327. Добавив перед числом 327 префикс специального символа \, получим требуемое:

nr.innerText=j+"\327"+i+"="+(i*j);

И, наконец, завершим оба цикла и всю функцию:

} } }

Мы только что рассмотрели функцию генерации таблицы построчно. Все же для наглядности приведем теперь ее текст целиком:

function writable(a,b,с,d) {
var i,j,nr,rnr;
for (i=c; i<=d; i++) {
nr=tbl.insertRow(i-c);
rnr=nr.rowlndex;
for (j=a; j<=b; j++) {
nr=tbl.rows[rnr].insertCell(j-a);
nr.innerText=j+"\327"+!+"="+(i*j);
}
}
}

Кстати, чтобы таблица была сгенерирована сразу же после загрузки страницы, добавим в элемент <BODY> связанный с ней обработчик событий onLoad:

<BODY onLoad="writable(2,9,2,10)">

Но это еще не все. Мы еще не написали функцию newtable(), которая должна удалить старое содержимое таблицы, взять значения из текстовых полей min1, max1, min2 и max2, проверить, являются ли они числами и, наконец, сгенерировать новую таблицу.

Удаление старой таблицы

Попробуем стереть содержимое таблицы. Вспомним, что есть метод deleteRow, который удаляет строку таблицы. Поскольку tbl.rows представляет собой массив, у него есть свойство length, которое содержит длину массива.

Кажется, что все ясно. Хочется написать

for (var i=0; i<tbl.rows.length; i++) tbl.deleteRow(i);

Вроде бы при этом мы должны пройтись по всему массиву и удалить все строки таблицы. Однако если вы запустите этот цикл, то увидите, что он удаляет не все содержимое таблицу. Строки удаляются через одну. Почему?

Давайте разберемся. Сначала счетчик i имеет значение 0, следовательно при первом проходе удаляется строка tbl.rows[0], а счетчик увеличивается на единицу. Но ведь при удалении самой первой строки таблицы все остальные строки изменяют свои номера! Бывшая строка tbl.rows[1] превращается в tbl.rows[0], tbl.rows[2] становится tbl.rows[1] и т. д. Соответственно, изменяется и значение tbl.rows.length (оно уменьшается на единицу).

Теперь, когда при втором проходе мы удаляем строку tbl.rows[1], выясняется, что строка tbl.rows[0] осталась нетронутой! То же самое происходит и далее. В следующий раз будет удалена строка tbl.rows[2], хотя к тому времени уже появится новая строка tbl.rows[1], и т. д.

Итак, для того чтобы действительно удалить одну за другой все строки таблицы, нам вообще не нужно увеличивать счетчик цикла! Строки сами меняют свои номера, а кроме того, уменьшается и значение tbl.rows.length (размер массива), так что, когда он станет равным 0, цикл автоматически завершится!

Вот как можно удалить все содержимое таблицы:

for (var i=0; i<tbl.rows.length; i) tbl.deleteRow(i);

Конечно, многое в этой записи служит лишь наглядности. Поскольку счетчик цикла не изменяется, то он, собственно говоря, вообще не нужен. Более коротко можно написать так:

for ( ; 0<tbl.rows.length; ) tbl.deleteRow(0);

Результат будет тем же.

Проверка параметров таблицы

Собственно говоря, далее в этом примере особых проблем нет. Запишем значения текстовых полей во временные переменные:

var z=min1.value;
var x=max1.value;
var c=min2.value;
var v=max2.value;

Теперь произведем с ними те же проверки и преобразования, что и в примере из главы 6:

if ((isNaN(z)==true) || (z==null)) z="2";
if ((isNaN(c)==true) || (c==null)) c="2";
if ((isNaN(x)==true) || (x==null)) x="9";
if ((isNaN(v)==true) || (v==null)) v="10";
z=parseInt(z) ;
c=parseInt(c);
x=parseInt(x);
v=parseInt(v);
if (x<=z) x=z+1;

if (v<=c) v=c+1;

На всякий случай запишем результат наших преобразованй обратно в текстовые поля (это нужно, чтобы пользователь, который ввел «неправильное» значение, мог видеть, на что оно изменилось):

min1.value=z;
max1.value=x;
min2.value=c;
max2.value=v;

И, наконец, сгенерируем таблицу, вызвав написанную нами ранее функцию writable:

writable(z,x,с,v);

Вот и все! В этом примере мы ограничли количество символов, вводимых в поля, до трех, то есть пользователь не сможет ввести число, большее чем 999. Однако это ограничение легко снять, просто изменив значение атрибута MAXLENGTH= текстовых полей.

Давайте посмотрим, что у нас получилось.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<ТIТLЕ>Таблица умножения</ТITLЕ>
</HEAD>
<STYLE>
BODY { text-align: center;
background-color: #FCF7EC;
}
TD { text-align: right; }
</STYLE>
<SCRIPT LANGUAGE=" JavaScript" TYPE="text/javascript">
<!--
function writable (a, b, c,d) {
var i, j ,nr, rnr;
for (i=c; i<=d; i++) {
nr=tbl . insertRow (i-c) ;
rnr=nr . rowIndex;
for (j=a; j<=b; j++) {
nr=tbl . rows [rnr] . insertCell ( j-a) ;
nr.innerText=j+"\327"+i+"="+(i*j) ;
} } }
function newtable() {
for (var i=0; i<tbl . rows . length; i) tbl .deleteRow (i) ;
var z=min1.value;
var x=max1 .value ;
var c=min2 .value;
var v=max2 .value;
if ((isNaN(z)==true) | | (z==null)) z="2";
if ( (isNaN(c)==true) | | (c==null) ) c="2";
if ( (isNaN(x)==true) | | (x==null) ) x="9";
if ( (isNaN(v)==true) | | (v==null) ) v="10";
z=parseInt (z) ;
c=parseInt (c) ;
x=parseInt (x) ;
v=parseInt (v) ;
if (x<=z) x=z+1;
if (v<=c) v=c+1;
min1 .value=z;
max1 .value=x;
min2 .value=c;
max2 .value=v;
writable (z, x, c, v) ;
}
//-- >
</SCRIPT>
<BODY onLoad="writable (2, 9,2, 10) ">
<Н2>ТАБЛИЦА УМНОЖЕНИЯ</Н2>
Первый множитель: от <INPUT TYPE="text" NAME="min1" VALUE="2" SIZE="3" MAXLENGTH="3" onChange="newtable () "> до <INPUT TYPE="text" NAME="maxl" VALUE="9" SIZE="3" MAXLENGTH="3" onChange="newtable ( ) "><BR>

Второй множитель: от <INPUT TYPE="text" NAME="min2" VALUE="2" SIZE="3" MAXLENGTH="3" onChange="newtable () ">
до <INPUT TYPE="text" NAME="max2" VALUE="10" SIZE="3" MAXLENGTH="3" onChange="newtable ( ) "><BR>

<BR>
<TABLE ID="tbl" BORDER="1" CELLSPACING="0" CELLPADDING="2" RULES="cols">
</TABLE>
</BODY>
</HTML>

Конечно, в этой таблице можно еще многое улучшить. Например, можно ввести запрет на ввод отрицательных чисел. Можно сделать что-нибудь более интересное, например добавить поле для ввода математического действия, чтобы легко преобразовывать эту таблицу в таблицу сложения или таблицу возведения в степень. Попробуйте сделать это самостоятельно.

Таблица с вычисляемыми элементами

Теперь давайте рассмотрим еще один небольшой пример на доступ к содержимому таблицы. Если помните, в главе 2 мы создавали страницу «Турнирная таблица» (см. рис. 2.13). Предположим, что вы регулярно ее обновляете в течение всего чемпионата, занося туда результат каждого сыгранного матча. При этом вам приходится вручную пересчитывать количество очков, а также забитых и пропущенных шайб. Но ведь это та работа, которую вполне можно поручить компьютеру! Давайте рассмотрим, как написать функцию, автоматически подсчитывающую эти результаты.

Итак, в две последние ячейки каждой строки (кроме первой, «заголовочной») мы изначально не заносим ничего:

<TR>
<TD ALIGN="center">1</TD>
<TD>&laquo;POTOP&raquo;</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">6:4</TD>
<TD ALIGN="center" BGCOLOR="white">2:3</TD>
<TD ALIGN="center" BGCOLOR="white">7:3</TD>
<TD ALIGN="center" BGCOLOR="white">2:1</TD>
<TD ALIGN="center" BGCOLOR="white">0:0</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR> (и т.д.)

Нам нужно, чтобы сразу после загрузки страницы некоторая функция — назовем ее count() — подсчитала результаты и занесла их в соответствующие ячейки таблицы. Для этого поместим в тег <BODY> обработчик событий onLoad:

<BODY BGCOLOR="#FFFFB3" TEXT="#202020" LINK="#400080" VLINK="#400080" ALINK="#400080" onLoad="count()">

Кроме того, для быстрого доступа к таблице присвоим ей уникальное имя tur:

<TABLE ID="tur" ALIGN="center" BGCOLOR="#E4E4E4" WIDTH="100%" CELLSPACING="0" CELLPADDING="2" BORDER="3">

Теперь напишем саму функцию count(). Начнем ее с того, что объявим локальные переменные, которые будем использовать для подсчета забитых шайб, пропущенных шайб и очков соответственно:

var zab, prop, och;

Потом организуем цикл, в котором пройдемся по всем строкам таблицы, кроме «заголовочной». Будем использовать счетчик цикла в качественомера строки. Поскольку нулевая строка нам не нужна, счетчик будет принимать значения от 1 до 6:

for (var i=1; i<=6; i++) {

В начале прохода каждой строки нужно, прежде всего, обнулить значения переменных zab, prop и och (изначально каждая команда имеет 0 очков и по 0 забитых и пропущенных шайб). Сделаем это одной строкой:

zab=prop=och=0;

Теперь настало время просмотреть каждую ячейку таблицы в данной строке. Для этого организуем второй цикл. При этом учтем, что ячейки с номерами 0 и 1 нам не потребуются (там находятся номер и название команды). Кроме того, не нужно просматривать и две последние ячейки в строке, с номерами 8 и 9, поскольку изначально там ничего нет:

for (var j=2; j<=7; j++) {

При просмотре каждой из ячеек нас будет интересовать ее содержимое, то есть свойство innerText. Для обращения к нему нужно будет использовать довольно длинную запись tur.rows[i].cells[j].innerText. Поскольку она явно будет использоваться внутри цикла неоднократно, для сокращения кода определим временную переменную cll, которая содержит обращение к содержимому текущей ячейки:

var cll=tur.rows[i].cells[j].innerText;

Анализ данных

Поскольку результаты есть не во всех ячейках, то прежде, чем приступать к каким-либо действиям, необходимо проверить наличие записи о результате матча в данной ячейке. Воспользуемся тем фактом, что счет матча мы всегда записываем через двоеточие (например 4:2). Значит, если в тексте ячейки присутствует двоеточие, то в ней есть и результат матча. Здесь нам очень поможет метод indexOf(), который возвращает в качестве результата номер позиции заданного символа в строке, а если заданный символ не обнаружен, то возвращается значение -1. Поэтому в качестве проверки мы можем написать:

if (ell.indexOf(":")!=-1) {

— и все действия, находящиеся в следующем блоке, будут выполнены, только если в ячейке присутствует результат.

Но как выделить из содержимого ячейки количество забитых шайб? Очевидно, что с него начинается запись результата, но ведь оно может быть и двузначным числом (или даже трехзначным, если записывать результаты не хоккейного, а баскетбольного турнира). Поэтому нам нужно выделить подстроку, начинающуюся с первого символа (позиция 0) и заканчивающуюся символом двоеточия. Хотя мы и не знаем номер позиции двоеточия, здесь нам на помощь придет метод indexOf(). Затем нужно будет превратить полученную подстроку в число. Для этого можно воспользоваться функцией parseInt().

Для удобства запишем результат в еще одну временную переменную:

var z=parseInt(ell.substring(0,ell.indexOf(":")));

Аналогично выделим из содержимого ячейки количество пропущенных шайб. Это должна быть подстрока, начинающаяся с символа, следующего сразу за двоеточием, и заканчивающаяся последним символом в ячейке:

var p=parseInt(ell.substring(ell.indexOf(":")+1,cll.length)); Теперь увеличим переменные zab и prop на вычисленные величины:

zab+=z; prop+=p;

Ну, а сейчас нужно еще разобраться с подсчетом очков. Поскольку коли-чество пропущенных и забитых шайб. Мы уже выяснили и записали в переменные z и р, осталось сравнить их и в зависимости от результата увеличить переменную och на 2 или 1, или вообще оставить ее без изменения:

z>р ? och+=2 : z==p ? och++ : z ;

Здесь мы использовали сокращенную форму условного оператора if. Последняя буква z в этой строке, вообщет говоря, не нужна. Но некоторые интерпретаторы JavaScript не признают в сокращенной записи « пустого оператора» и для них приходится заполнить пространство хоть чем-то. С таким же успехом мы могли написать, например, z++ (все равно в следующей строке будет осуществлен выход из цикла, и локальная переменная z закончит свое существование).

Теперь закроем блок if и внутренний цикл (перебор ячеек строки):

} }

Запись результатов

А внешний цикл (перебор строк) закрывать еще рано. Ведь мы еще не сделали самое главное - не записали результаты в две последние ячейки строки. Поскольку эти результаты у нас уже есть (они подсчитаны и хранятся в переменных zab, prop, и och), записать их в ячейки уже нетрудно:

tur.row[i].cells[8].innerText=zab+"-"+prop;
tur. rows [i].cells [9]. innerHTML="<B><BIG>"+och+"</BIG></B>";

В последнем случае нам прищлось использовать свойство innerHTML, а не innerText, чтобы поместить в ячейку теги форматирования. После этого можно закрывать цикл перебора ячеек.

Давайте взглянем на весь текст получившейся функции:

function count() {
var zab, prop, och;
for (var 1=1; i<=6; i++) {
zab=prop=och=0;
for (var j=2; j<=7; j++) {
var cll=tur.rows[i].cells[j].innerText;
if (ell.indexOf(":")!=-1) {
var z=parseInt(ell.substring
(0,cll.indexOf(":")));
var p=parseInt(cll.substring
(cll.indexOf(":")+1,cll.length));
zab+=z;
prop+=p;
z>p ? och+=2 : z==p ? och++ : z ;
} } tur.rows[i].cells[8].innerText=zab+"-"+prop;
tur.rows[i] .cells[9] . innerHTML="<B><BIG>"+och+"
</BIG></B>";

} }

Теперь можно заносить результаты в таблицу постепенно, а функция count() будет автоматически изменять два последних столбца таблицы. Например, вот как может выглядеть эта страница после трех туров турнира:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Турнирнирная таблица</ТIТLЕ>
<SCRIPT LANGUAGE=" JavaScript" TYPE="text/ javascript">
<!--
function count () {
var zab, prop, och;
for (var 1=1; i<=6; i++) {
zab=prop=och=0 ;
for (var j=2; j<=7; j++) {
var cll=tur .rows [i] .cells [j] .innerText;
if (cll. indexOf (":")!=-1) {
var z=parseInt (cll. substring (0, cll. indexOf (":"))) ;
var p=parseInt (cll. substring (ell . indexOf (":")+1, cll . length) ) ;
zab+=z;
prop+=p;
z>p ? och+=2 : z==p ? och++ : z ; }
}
tur.rows[i] .cells [8] . innerText=zab+"— "+prop;
tur.rows[i] .cells [9] . innerHTML="<B><BIG>"+och+"</BIG></B>";
} }
//-- >
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFB3" TEXT="#202020" LINK="#400080" VLINK="#400080" ALINK="#400080" onLoad="count () ">
<DIV ALIGN="center">
<Н1>ВТОРОЙ ЧЕМПИОНАТ ГОРОДА ПО ХОККЕЮ</Н1>
<НЗ>ТАБЛИЦА РЕЗУЛЬТАТОВ</НЗ>
</DIV>
<TABLE ID="tur" ALIGN="center" BGCOLOR="#E4E4E4" WIDTH="100%" CELLSPACING="0" CELLPADDING="2" BORDER="3">
<TR>
<TD WIDTH="20" ALIGN="center">&nbsp;</TD>
<TD WIDТН="20%">Команда</ТD>
<TD WIDTH="40" ALIGN="center">1</TD>
<TD WIDTH="40" ALIGN="center">2</TD>
<TD WIDTH="40" ALIGN="center">3</TD>
<TD WIDTH="40" ALIGN="center">4</TD>
<TD WIDTH="40" ALIGN="center">5</TD>
<TD WIDTH="40" ALIGN="center">6</TD>
<TD ALIGN="center">Шaйбы</TD>
<TD ALIGN="center">Очки</TD>
</TR>
<TR>
<TD ALIGN="center">1</TD>
<TD>&laquo; POTOP&raquo; </TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">0:2</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">6: 1</TD>
<TD ALIGN="center" BGCOLOR="white">6: 0</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR>
<TR>
<TD ALIGN="center">2</TD>
<TD>&laquo;POTATOP&raquo;</TD>
<TD ALIGN="center" BGCOLOR="white">2 : 0</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">3 : 4</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">2:5</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR>
<TR>
<TD ALIGN="center">3</TD>
<TD>&laquo;УPOЖAЙ&raquo;</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">4 :3</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">7 :2</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">l :1</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"> </TD>
</TR>
<TR>
<TD ALIGN="center">4</TD>
<TD>&laquo;MAЧTA&raquo;</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">2 :7</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">2 : 5</TD>
<TD ALIGN="center" BGCOLOR="white">l : 3</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR>
<TR>
<TD ALIGN="center">5</TD>
<TD>&laquo;MEЧTA&raquo;</TD>
<TD ALIGN="center" BGCOLOR="white">l : 6</TD>
<TD ALIGN="center" BGCOLOR="white">5 :2</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">5 :2</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR>
<TR>
<TD ALIGN="center">6</TD>
<TD>&laquo;OKAЗИЯ&raquo;</TD>
<TD ALIGN="center" BGCOLOR="white">0 : 6</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD ALIGN="center" BGCOLOR="white">l : 1</TD>
<TD ALIGN="center" BGCOLOR="white">3: 1</TD>
<TD ALIGN="center" BGCOLOR="white">&nbsp;</TD>
<TD BGCOLOR="black"></TD>
<TD ALIGN="center" BGCOLOR="#DFFFDF"></TD>
<TD ALIGN="center" BGCOLOR="#FF8484"></TD>
</TR>
</TABLE>
</BODY>
</HTML>

Результат показан на рис. 7.20. Обратите внимание на то, что в те ячейки, в которые еще не помещены результаты, поставлен неразрывный пробел (&nbsp;). Это сделано, чтобы границы между ячейками не прерывались. Можно попробовать улучшить и эту страницу. Например, попробуйте добавить в нее столбцы для отображения количества проведеных игр, выигрышей, ничьих и поражений, а также для отображения места, которое занимает команда. Можно сделать так, чтобы эти столбцы пользователь мог отобразить или скрыть по желанию. Кроме того, можно поставить задачу отсортировать таблицу так, чтобы наверху всегда была команда, занимающая первое место, затем второе и т. д. Однако это несколько сложнее, чем может показаться на первый взгляд: ведь придется сортировать не только строки, но и столбцы.

Рис.7.20. В эту турнирную таблицу не нужно вручную вносить значенияв столбцы «Шайбы» и «Очки» — они изменяются автоматически при внесении нового результата

Hosted by uCoz