Иллюстрированный самоучитель по созданию сайтов

         

Реакция на нажатие клавиши


Давайте попробуем реализовать эту возможность. Для начала назначим элементу

<BODY>

обработчик событий, реагирующий на нажатие клавиш. Он называется onKeyPress:

<BODY onKeyPress="press()">

Теперь давайте напишем саму функцию press(), которая будет вызываться при нажатии какой-либо клавиши. Поскольку у нас в примере букв всего шесть (от А до Е), то пусть нажатие на эти клавиши будет перемещать нашу страницу к соответствующей букве. Нажатие на любую другую клавишу можно обработать как перемещение в начало файла.

Обратите внимание на то, что для организации доступа к каждой букве (и к началу файла) нам не придется прикладывать никаких дополнительных усилий! Ведь мы уже ранее создали соответствующие якоря с помо щью тега <А>, и хотя они и не имеют атрибута ID=, у них есть атрибут NAME=, который тоже можно использовать для доступа к элементам.

Итак, при нажатии на клавишу нужно проверить, какая буква была нажата. Это можно сделать, прочитав значение свойства window event keyCode. Оно равно ASCIIJ-коду нажатой клавиши. Например, если нажата клавиша с русской буквой а, то значение свойства window event keyCode равно 1072, то есть коду этой буквы.

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

switch(window.event.keyCode) { case 1072: // какие-то действия case 1073: // какие-то действия и т.д.

Чтобы прокрутить страницу к заданному элементу, можно воспользоваться методом scrolllntoView( ). Например, если мы напишем

document.all.BukvaA.scrolllntoView() ;

то в результате страница будет прокручена так, что якорь BukvaA окажется в верхней части окна броузера.



Реакция на нажатие кнопки


Сначала добавим в тег

<BODY>

обработчики событий, реагирующие на нажатие кнопки мыши (не на щелчок, который состоит из нажатия и отпускания левой кнопки, а именно на нажатие) — onMouseDown, на отпускание кнопки — onMouseUp и на движение указателя мыши — onMouseMove:



<BODY onLoad="mainpos()" onMouseDown="down_it()" onMouseUp="up_it()" onMouseMove="move_it()">

Рис. 7.10. Изменение порядка следования позиционированных элементов

<IMG>

позволяет изменить их расположение в третьем измерении

Теперь осталось написать функции, которые мы так лихо назначили обработчикам событий. Сначала давайте займемся нажатием кнопки мыши (onMouseDown).

Прежде всего, нам надо определить, была ли нажата кнопка мыши на рисунке одной из плашек. Если нет, то ничего делать не нужно. Как проверить это условие? В Internet Explorer 4+ источник каждого события записывается в свойство window.event.srcElement. Но что нам это дает? Ведь нужных нам рисунков целых 15, и у каждого есть свое уникальное имя (свойство ID=). Неужели придется сравнивать свойство window.event.srcElement id с каждым именем?

Мы совсем забыли, что каждый рисунок плашки представляет собой тег

<IMG>.

Поэтому мы можем сравнить свойство window.event.srcElement.tagName, содержащее названия тега-источника события, со словом IMG, и в случае удачи перейти к дальнейшим действиям:

function down_it() { if(window.event.srcElement.tagName=="IMG") { // какие-то действия } }

Стоп! Но ведь, кроме рисунков плашек, у нас еще есть прозрачный рисунок, расположенный в каждой из шестнадцати ячеек таблицы! А вот его-то нам никуда передвигать совсем не нужно. При этом от рисунков плашек его отличает только свойство SRC=. Придется сравнить это свойство со значением Images/diafanol.gif, и продолжать дальнейшую работу функции лишь в том случае, если совпадение не обнаружится.

Однако если мы напишем:

if ( (window, event. srcElement. tagName

s

""IMG") && (window.event.srcElement.src!="Images/diafanol.gif")) {


// какие-то действия }

то в большинстве случаев нас постигнет разочарование: “какие-то действия” все равно будут выполняться, даже если кнопка мыши будет нажата на прозрачном рисунке! В чем же дело?

Оказывается, свойство window.event.srcElement.src в любом случае содержит указание на абсолютное местоположение файла рисунка. Так, например, если эти опыты мы проводим на локальном компьютере, то значением window.event.srcElement.src будет полный путь доступа к файлу, включающий имя диска и родительские папки. Поскольку при разработке страницы, скорее всего, еще нельзя точно предсказать этот путь доступа, да и проверить работу страницы на локальном компьютере тоже нелишне, придется поступить по другому. Воспользуемся тем, что каково бы ни было абсолютное расположение файла, значение window.event.srcElement.src все равно будет заканчиваться его именем — в нашем случае diafanol .gif. то есть символы с 13-го по 5-й от конца строки будут заведомо содержать значение diafanol. Поскольку длина любой строки всегда содержится в ее свойстве length, то мы можем выделить из полного названия файла нужные нам символы, начиная от length-12 и кончая length-4. Выделение части строки можно произвести методом substring:

if((window.event.srcElement.tagName=="IMG")&& (window.event.srcElement.src.substring (window.event.srcElement.src.length-12, window.event.srcElement.src.length-4)!="diafanol")) {

// какие-то действия }

Вот теперь все заработает правильно. Правда, строка условия выглядит очень громоздко. Мы не рекомендуем писать такие строки, поскольку через какое-то время с ними будет трудно разбираться, если вдруг понадобится что-то изменить. Например, в нашем случае можно определить локаль ную переменную 1 и присвоить ей значение window.event.srcElement.src.length. Тогда строка условия будет выглядеть хоть немного компактней:

if((window.eventssrcElement.tagName="IMG") && (window, event .'SrcElement. src.substring (1-12,1-4) != "diafanol"”

Какие же действия нужно осуществить внутри этой функции? Если вы еще не забыли, нам нужно “привязать” рисунок плашки к указателю мыши. Для этого достаточно определить глобальную переменную (мы назвали ее moving), и присваивать ей всегда имя рисунка, который необхо димо передвигать. Если никакой рисунок передвигать не нужно (кнопка мыши отпущена или нажата не на рисунке плашки), можно присвоить переменной moving значение " " (пустая строка). В самом начале сценария эту переменную можно объявить так:

var moving"";

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

moving=window.event.srcElement.id;


Реакция на отпускание кнопки


Теперь давайте займемся функцией up_it(), выполняющейся при отпускании кнопки мыши. Собственно говоря, все, что нужно сделать — это проверить, передвигался ли какой-нибудь объект (то есть, содержит ли переменная moving какое-либо имя) и, если это так, присвоить этой переменной пустую строку, что будет означать “освобождение” рисунка: function up_it() ( if (moving!="") moving="";

Однако хорошо бы еще расположить рисунок не где попало, а точно в ячейке таблицы. Поскольку в этом случае его координаты относительно начала таблицы должны быть кратны 100, это довольно легко осуществить. Для этoгo достаточно округлить его до ближайшей сотни. Для округления можно использовать встроенный метод Math.round. Понятно, что он округляет не до сотен, а до целых чисел, поэтому текущие координаты рисунка перед округлением придется разделить на 100, а после округления — умно жить на 100. Кроме того, не забывайте, что кратность 100 мы определяем относительно начала таблицы, которое равно tstart по горизонтали и 100 но вертикали. Поэтому перед делением на 100 нужно еще вычесть из горизонтальной координаты значение tstart, а в конце снова его прибавить. Вот что у нас получается:

document.all[moving].style.pixelLeft= Math.round;(window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

Как видите, все довольно просто. Здесь мы прибавили к каждой коорди нате еще по единице, чтобы рисунки не налезали на сетку таблицы. Кстати, ширину ячеек таблицы (то есть, прозрачного рисунка diafanol.gif) в этом случае тоже необходимо немного скорректировать. Поскольку каждая ячейка таблицы имеет со всех сторон бордюр шириной в 1 пиксел, придется сделать ширину самих ячеек равной не 100, а 98:

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


i

f (window.event.clientX>=tstart-50&&window.event,clientY>=50) {

document.all[moving].style.pixelLeft= Math.round((window.event.clientX-50-tstart)/100)*100+tstart+l;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)* 100+1;

}

И, наконец, еще один штрих. При перемещении некоторых рисунков может возникнуть ситуация, когда перемещаемый рисунок будет проходить как бы под другим, пропадая на время из видимости. Чтобы этого не возникало, давайте добавим в функцию down_it() еще такую строку:

document.all[moving].style.zlndex=5;

Поскольку у всех остальных элементов значение z-index не изменялось (и, следовательно, равно нулю), мы добиваемся того, что перемещаемый рисунок никогда не будет перекрыт другими объектами. Естественно, при окончании перемещения рисунка ему нужно возвратить исходное значение z-index. Для этого в функцию up_it() добавим строку

document.a 11[moving].style.zlndex=0; Итак, давайте посмотрим, что же у нас получается.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Иrpa 15</TITLE>

<STYLE> BODY { background-color: #979797; color: #FEFEFE;

text-align: center; font-weight: bold;

font-size: 30рх; font-family: sans-serif; }

</STYLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">

var tstart; var moving="";

function mainpbs( )

{ tstart=document.body.clientWidth/2-200;

document. a.is .rnaintab. style. left=tstart;

function down_it()

{ var 1==window. event. srcElement. src.length;

if((window.event.srcElement.tagName="IMG")&&

(window.event.srcElement.src.substring(1-12,1-4)!= "diafanol"))

{ moving=window.event.srcElement.id;

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style.pixelTop=window.event.clientY-50;

document.all[moving].style.zlndex=5; } } function up it() { if (moving!="") {



if (window.event.clientX>=tstart-50&& window.event.clientY>=50) {

document.all[moving].style.pixelLeft= Math.roundf(window.event.clientX-50-tstart)/100)*100+tstart+1;

document.all[moving].style,pixelTop= Math.round((window.event.clientY-50)/100)*100+1;

} document.all[moving].style.zlndex=0; moving=""; }

} function move it() { if (moving!="")

{ document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style.pixelTop==window.event.clientY-50 ;

} event.cancelBubble = true; event.returnValue = false; }

//—>

</SCRIPT>

</HEAD>

<BODY enLoad="mainpos()" опМouseDown="down it()" onMouseUp="up_it()" onMouseMove="move_it()">

Расставьте плашки перетаскиванием с помощью мыши

<DIV ID="maintab" STYLE="width: 400px; height: 400px; position: absolute; top: 100px;">

<TABLE BGCOLOR="#COCOCO" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BORDER="1">

<TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>



<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD> </TR> <TR>

<TD><IMG SRC="Images/diafanol.gif" HIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

<TD><IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"></TD>

</TR> </TABLE> </DIV>

<IМG ID="p11" SRC="Images/digitll.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="11" STYLE="position: absolute; top: 60px; left: 50px;

<IMG ID="pl2 SRC="Images/digitl2.gif" WIDTH="100" HEIGHT="100" BORDER="0" AtlT="12" STYLE="position: absolute; top: 160px; left: 50px;

<IMG ID="p13 SRC-"Images/digitl3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="13" STYLE="position: absolute; top: 260px; left: 50px;">

<IMG ID="pl4" SRC="Images/digitl4.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="14" STYLE="position: absolute; top: 36Орх; left: 50px;">

<IMG ID="pl5" SRC="mages/digitl5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="15" STYLE="position: absolute; top: 460px; left: 50px;">



<IMG ID="p6" SRC="Images/digit6.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="6" STYLE="position: absolute; top: 60px; left: 30px;">

<IMG ID="p7" SRC="Images/digit7.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="7" STYLE="position: absolute; top: 160px; left: 30px;">

<IMG ID="p8" SRC="Images/digit8.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="8" STYLE="position: absolute; top: 260px; left: 30px;">

<IMG ID="p9" SRC="Images/digit9.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="9" STYLE="position: absolute; top: ЗбОрх; left: 30px;">

<IMG ID="plO" SRC="Images/digitl0.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="10" STYLE="position: absolute; top: 460px; left: 30px;">

<IMG ID="pl" SRC="Images/digitl.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="1" STYLE="position: absolute; top: 60px; left: 10px;">

<IMG ID="p2" SRC="Images/digit2.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="2" STYLE="position: absolute; top: 160px; left: 10px;">

<IMG ID="p3" SRC="Images/digit3.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="3" STYLE="position: absolute; top: 260px; left: 10px;">

<IMG ID="p4" SRC="Images/digit4.gif" WIDTH="100" KEIGHT="100" BORDER="0" ALT="4" STYLE="position: absolute; top: ЗбОрх; left: 10px;">

<IMG ID="p5" SRC="Images/digit5.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="5" STYLE="position: absolute; top: 460px; left: 10px;">



</BODY>

</HTML>

Результат представлен на рис. 7.11. В принципе, в такую игру уже можно по-настоящему играть. Конечно, этот код можно еще упростить. Правильно, зачем шестнадцать раз повторять тег вставки прозрачного рисунка? Давайте заменим его вложенным циклом JavaScript:

for (var k=l; k<=4; k++) { document.write("<TR>") ;

for (var m=l; m<=4; m++) document.write('<TD> <IMG SRC="Images/diafanol.gif" WIDTH="98" HEIGHT="98"> </TD>') ;

document.write("</TR>");

}



Рис. 7.11. Реализация технологии drag-and-drop: пользователь может перетаскивать плашки с помощью мыши

Результат будет тот же. А если немного подумать, то можно сократить даже код первоначального расположения рисунков плашек, правда, это немного труднее.

Кроме того пока что мы никак не проверяем, не ставит ли пользователь две плaшки в одну и ту же ячейку, а уж о самой игре и говорить нечего. Но ведь мы пока только реализовывали расстановку плашек методом перетаскивания. Запомните рассмотренные в этом разделе приемы, так как они позволяют организовать столь любимую пользователями интерактивность просто на небывалом уровне — вспомните, что одна из функций реагировала у нас буквально на каждое перемещение указателя мыши!

К сожалению, приведенная выше страница будет работать только в Internet Explorer. Если необходимо, чтобы она работала также и в Netscape 6, придется приложить некоторые усилия. Дело в том, что помимо различий в син таксисе доступа к элементам, о котором мы уже говорили (в Netscape используется конструкция document.getElementByld вместо document.all), различия существуют также и в обработке событий. В частности, вместо глобального объекта event в Netscape необходимо использовать временную переменную, которой будет передаваться значение объекта event. Кроме того, вместо свойства srcElement используется свойство target, а свойство returnValue вообще не поддерживается.Выше мы приводили примеры того, как написать код, работающий в обоих популярных броузерах. Вы можете в качестве упраж нения попробовать это сделать и для данного примера, однако из-за обработки событий мыши это будет сложнее, чем в предыдущих случаях.


Реакция на перемещение мыши


В принципе, наша функция down_it() уже справляется со своими обязанностями. Теперь давайте займемся функцией moveit( ), которая будет вызываться при движении мыши.

Эта функция должна прежде всего проверить, нужно ли передвигать какой- либо рисунок. Как вы помните, его имя содержится в переменной moving. Так что нужно сначала сравнить значение переменной moving с пустой стро кой и в случае совпадения не предпринимать никаких действий:

function move it() { if (moving!="") { // какие-то действия

} }

Теперь давайте подумаем, что должно быть сделано, если переменная moving содержит имя рисунка, который нужно передвинуть. Очевидно, для того чтобы его передвинуть, нужно изменить его стилевые свойства left и top в соответствии с расположением указателя мыши. Текущее положение указателя мыши можно узнать, прочитав значения свойств window.event.clientX и window.event.clientY.

— Стоп! — скажете вы. — А как узнать, как должен располагаться рису нок относительно указателя мыши? Ведь пользователь может щелкнуть и в центре рисунка, и с краю, и в любом другом месте. Значит, в функции down_it(), которую мы считали уже законченной, нужно еще вычислить координаты указателя мыши относительно рисунка?

— Правильно! Это обязательно нужно сделать, если применять эту технологию для перетаскивания крупных объектов. Но в нашем примере мы позволим себе упростить задачу, воспользовавшись тем, что наши плашки имеют относительно небольшие размеры. При таких размерах будет вполне нормально, если при перетягивании рисунка указатель мыши будет находиться посередине его. Поскольку рисунки наши имеют размер 100х100, нам остается вычесть 50 из каждой координаты указателя мыши и при своить эти значения свойствам left и top рисунка:

document.all[moving].style.pixelLeft=window.event.clientX-50; document.all[moving].style,pixelTop=window.event.clientY-50;

Обратите внимание на то, что для обращения к объекту по его имени, содержащемуся в переменной, необходимо использовать квадратные скобки, то есть писать document.all[moving], а не document.all.
moving. В противном случае броузер не сможет найти нужный объект и выдаст сообщение об ошибке

. Кроме того, обратите внимание на то, что для корректного изменения координат в Internet Explorer необходимо использовать свойства pixelLeft и pixelTop вместо left и top.

Из эстетических соображений давайте передвинем центр рисунка к указателю мыши уже в функции down_it(), добавив туда две точно такие же строки. Что касается функции moveJt(), то она почти готова. Однако необходимо добавить в нее еще две строки, чтобы предотвратить заранее предопределенную реакцию броузера на какие-либо ситуации:

window.event.cancelBubble = true; window.event.returnValue = false;

Первая из этих строк отменяет так называемое “всплытие” события, то есть возникновение его в элементах страницы, содержащих элемент-источ ник

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

window.event.returnValue = false;

тo рисунки начнут “тормозиться” уже при небольшом перемещении, после чего броузер может вообще не распознать отпускание кнопки мыши. Мы сейчас не будем вдаваться в подробности того, почему так происходит. Однако запомните, что эти две короткие строчки при обработке событий мыши часто помогают избежать многих неприятностей. Если у вас что-то не получается, проверьте, а не “всплывает” ли какое-нибудь нежелательное событие? И не пытается ли броузер делать что-то “свое” вместо назначенных вами операций?


Реализация операций перетаскиванием


Итак, мы рассмотрели несколько основных обработчиков событий. Однако существуют и другие события мыши. Например, веб-страница может отдельно реагировать на нажатие кнопки мыши, на ее отпускание и даже на ее движение. Для чего это может понадобиться? Одно из возможных применений — это реализация так называемой технологии drag-and-drop, (проще говоря — перетаскивания экранных объектов с помощью мыши. Для иллюстрации рассмотрим несложный пример.

Предположим, вы хотите проиллюстрировать на своей странице знаменитую игру Лойда “Пятнадцать”, например так, как показано на рис. 7.7. Нужно, вроде бы, сначала просто задать стиль для текста:

<STYLE> BODY { . background-color: #979797; color: #FEFEFE; text-align: center;

font-weight: bold; font-size: 30рх;

font-family: sans-serif; . } </STYLE>

затем вывести на экран заголовок; потом создать центрированный блок (

<DIV>

) с фиксированной шириной и высотой, а также небольшим отсту- пом сверху, заданным с помощью стилевого свойства margin-top:

<DIV ALIGN="center" STYLE="width: 400px; height: 400px; margin-top: 25px;">

Теперь осталось вставить в этот блок таблицу, у которой был бы опреде лен фоновый цвет, отличающийся от основного фона страницы, а также тонкие границы между ячейками:

Рис. 7.7. Страница, иллюстрирующая игру “Пятнадцать”

<TABLE BGCOLOR="#COCOCO" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BORDER="1">

и в каждую ячейку этой таблицы поместить заранее подготовленное изображение плашки с цифрой', например, вот так:

<TD WIDTH="25%" ID="cl"><IMG SRC="Images/digitl.gif" WIDTH="100" HEIGHT="100" BORDER="0" ALT="1"></TD>

Вообще говоря, поскольку ширина (и высота) рисунков определены в 100 пикселов, атрибут WIDTH= указывать для тега <TD> совсем не обязательно. Что же касается атрибута ID=, то мы здесь указали его с расчетом на то, что плашки придется переставлять, и тогда потребуется доступ к ячейкам таблицы.


Все это замечательно, если исходная позиция задана изначально. Однако предположим, что мы хотим дать пользователю возможность самому рас ставить плашки. Пусть в начале игры все они расположены вне игрового поля. Можно даже расположить их друг на друге. Пользователь при этом должен иметь возможность перетянуть мышью каждую из плашек на одну из клеток игрового поля. Для этого придется сделать три вещи.

Во-первых, при нажатии кнопки мыши нужно определить, в каком месте окна броузера она нажата. Если нажатие произошло на рисунке плашки, нужно сразу же “привязать” этот рисунок к указателю мыши, чтобы он передвигался вместе с ним, пока кнопка не будет отпущена.

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

И, в-третьих, при отпускании кнопки мыши нужно оставить рисунок на том месте, куда он был передвинут.


Редактор Star Office


Более мощными средствами редактирования HTML-файлов располагает программа StarOffice. Здесь при открытии или создании

HTML-

файла соответственно меняется содержимое некоторых меню, что позволяет достаточно эффективно работать с

HTML

кодом. Самым приятным моментом здесь, пожалуй, является возможность установить флажок HTML Source (Исходный код HTML) в меню View (Вид), который отключает режим

WYSIWYG

и позволяет работать с исходным HTML-текстом, в котором все теги и их атрибуты подсвечены красным цветом. По своему усмотрению можно редактировать как исходный текст, так и отображаемый результат, переключаясь между режимами командой HTML Source (Исходный код HTML) из меню View (Вид). В отличие от других WYSIWYG-редакторов, StarOffice довольно корректно удаляет ненужные элементы при отмене пользователем каких-либо действий и не вставляет лишних комментариев. При этом он довольно активно использует каскадные таблицы стилей

(CSS).

Перед подсветкой теги проверяются на корректность — ошибочно написанные теги красным цветом не выделяются. Однако надо иметь в виду, что программа не понимает новых тегов, таких, как

<BUTTON>

,

<LABEL>

и пр.



Регистрация имен


А как быть, если хочется сделать адрес странички более коротким, запоминающимся? Для этого существуют многочисленные службы переадресации, например: come.to, www.da.ru, attend.to (все названия реальные). Например, если Сергей Сергеев разместил на своей страничке информацию о своей фирме “Филин”, он может бесплатно зарегистрировать такие имена, как filin.da.ru(или www.filin.da.ru), come.to/filin и т. п. При этом пользователь, набравший эти адреса в своем броузере, будет автоматически переадресовываться на веб-страничку, размещенную где угодно: на сервере провайдера, на сервере Geocities или еще где-нибудь.

Ну, а если вы хотите приобрести для себя домен второго уровня (например www.filin.ru), то вам придется обратиться в соответствующую организацию. Так, например, распределением имен в домене .ru занимается организация РосНИИРОС (www.ripn.ru). За регистрацию в этом случае придется заплатить деньги, однако в итоге вы будете иметь легко запоминающийся адрес. Кстати, многие пользователи, игнорируя услуги поисковых машин, часто пытаются найти веб-странички, набирая наугад адреса типа www.имя.Компания.ru, так что, имея такое имя, вы получаете большие шансы на посещение.

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



Самое главное на любой веб-странице — гиперссылки


В предыдущем разделе мы рассмотрели различные способы форматирования текста веб-страницы. Однако созданная нами в качестве примера “Домашняя страница Сергея Сергеева” имеет существенный недостаток: она представляет собой голый текст. И дело тут вовсе не в отсутствии графики или звуковых фрагментов (графика и звук, конечно, украшают страничку, но в данном случае не это главное). Дело в отсутствии гиперссылок. Гилерссылки — контекстные связи между расположенными в Интернете материалами. Они являются основой построения World Wide Web. Обычно пользователи любят страницы, насыщенные гиперссылками, и это естественно: приятно, когда есть возможность легко получить более подробную информацию по каждой представленной теме.

В принципе, любое слово, встречающееся на веб-странице, можно превратить в гиперссылку, если известны какие-либо другие страницы, описывающие этот предмет более подробно. Так, например, на странице, посвященной описанию жизни в блокадном Ленинграде, в том месте, где речь идет об исполнении седьмой симфонии Шостаковича, помещена гиперссылка на страницу с биографией этого композитора. А на странице, посвященной компьютерной игре Quake, в углу указано, что теперь в нее можно играть и на компьютерах с операционной системой Linux — и в этом месте есть гиперссылка на страницу, с которой можно загрузить дистрибутив этой операционной системы. Щелкая кнопкой мыши по гиперссылкам, можно в принципе обойти хоть весь Интернет (точнее, его службу WWW).

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

• ссылки в другие места той же страницы; • ссылки на другие страницы этого же сайта или сервера;

• ссылки на страницы, расположенные на любом другом сервере в Интернете.


Локальные гиперссылки

Итак, начнем. На нашей страничке, представленной выше, есть три раздела: вступительный текст, сказка и рассказ. Конечно, поскольку это только пример, то все тексты небольшие (сочинять полностью сказки за Сергея Сергеева автору было недосуг) и, скорее всего, на экране эта страничка видна почти целиком. Однако представьте себе, что и вступительный текст, и рассказы занимают довольно большой объем (например, два экрана). В этом случае некорректно вынуждать пользователя перемещаться по странице только с помощью полос прокрутки. Кроме того, он может и не заметить, что помимо вступительного текста, на страничке есть еще что-то, если не дочитает текст до конца. В этом случае хорошим тоном будет прямо наверху странички поставить гиперссылки на оба рассказа.

Чтобы это сделать, надо сначала определить места, где эти рассказы начинаются, как “якоря” (места, к которым можно будет быстро переместиться). Для этого используют тег

<А>

. Это можно сделать, например, так:

<A NAME="skazka">ИВАН- ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ</А>

В данном случае мы определяем атрибут NAME= — имя якоря. По этому имени мы и будем на него ссылаться.

Для установки гиперссылки также используется тег

<А>

, но с установленным атрибутом HREF=. Значение этого атрибута определяет, что отобразится на экране, если пользователь щелкнет кнопкой мыши на гиперссылке. Чтобы сослаться на якорь, нужно просто указать в качестве значения HREF= имя этого якоря, перед которым расположен знак #:

<A HREF="#skazka">Сказка &laquo;Иван-царевич и серый заяц&raquо;</А>

Вce, что находится внутри тега гиперссылки, отображается в броузере подчеркнутом виде и другим цветом, а указатель мыши при наведении на

гиперссылку принимает вид руки с вытянутым указательным пальцем. По этим признакам читатель понимает, что перед ним гиперссылка.

Точно таким же образом можно поставить гиперссылку на второй рассказ. По умолчанию в большинстве броузеров гиперссылки отображаются синим цветом, что совершенно не гармонирует с цветовой гаммой нашей странички.


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

<BODY>

установить значение атрибута LINK=. Цвет можно выбрать по своему усмотрению, можно даже сделать гиперссылки тем же цветом, что и основной текст. Но вот этого как раз делать не рекомендуется, поскольку читатель не сможет быстро понять, где гиперссылка, а где нет. Обычно лучше всего подобрать цвет, близкий по оттенку к основному, однако отличающийся от него, например, по яркости. В нашем случае можно написать так:

<BODY BGCOLOR="#BABAAO" TEXT="#1D1D18" LINK="#634438">

Однако этого недостаточно. Дело в том, что броузер обычно отображает гиперссылки, которыми читатель еще не пользовался, одним цветом, а “посещенные” — другим. Этот цвет выбирается с помощью атрибута VLINK= тега

<BODY>

. Кроме того, есть еще атрибут ALINK=, который определяет цвет так называемой активной ссылки, то есть той, на которой в данный момент происходит щелчок кнопкой мыши. В большинстве случаев он почти не заметен (ведь появляется он только на долю секунды, если только у читателя нет привычки нажать кнопку мыши и долго ее не отпускать). Полное определение цветовой схемы страницы в теге

<BODY>

может выглядеть так:

<HTML>

<HEAD>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">

<META NAME="Generator" CONTENT="Microsoft Word 97">

<TITLE>Домашняя страница Сергея Cepreesa</TITLE>

<META NAME="Template" CONTENT="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#babaa0">

 <DIV aling="center"><h1>Домашняя страница Сергея Сергеева</h1> </div>

</FONT><FONT SIZE=1><P><BR>

<div align="center"><a href="#skazka">Сказка &laquo;Иван-царевич и серый заяц&raquo;</A>&nbsp;



<A HREF="#rasskaz">Рассказ &laquo;Молоток&raquo;</a></div>

</FONT><B><FONT FACE="Times New Roman">Сергей Сергеев - писатель-авангардист, автор 20 рассказов. <BR>

В жизни большой любитель собак и компьютерных игр. <BR>

<BR>

Некоторые его рассказы вы можете прочитать прямо здесь. </P>

</FONT><P><HR WIDTH="75%"></P>

</B><FONT FACE="Times New Roman"><H2 ALIGN="CENTER">ИBAH-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ <BR>

сказка</H2>

<P ALIGN="RIGHT">Hy, погоди!.. <BR>

(Из мультфильма)</Р></FONT> </P>

<FONT FACE="Times New Roman"><P ALIGN="JUSTIFY">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный... <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Долго ли, коротко ли ... <BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;И они жили долго и счастливо и умерли в один день.</Р></FONT> </P>

<P><HR WIDTH="75%"></P>

<FONT FACE="Times New Roman"><H2 ALIGN="CENTER">MOЛOTOK <BR>

рассказ</H2>

<P ALIGN="RIGHT">Mы кузнецы, и дух наш молод. <BR>

(Из песни)</P>

<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </P></FONT>

</BODY>

</HTML>

Результат показан на рис. 2.7. Если мы теперь щелкнем на какой-либо из гиперссылок, то страница “скакнет” вниз, так, чтобы текст нашего якоря отображался вверху экрана. (Однако, если при этом для заполнения экране не будет хватать текста, то текст якоря может оказаться не на самом верх страницы, а несколько ниже.)



Рис. 2.7. Применение внутренних гиперссылок


Схема сайта


Средства третьей вкладки — Site View (Схема сайта) — предназначены для просмотра схемы разрабатываемого веб-сайта. Связи между

HTML-

документами, рисунками и прочими объектами на схеме показаны пунктирными наглядно увидеть связи между элементами. Щелчок мыши на каком-либо элементе схемы приводит к выделению соответствующего элемента в окне редактирования.

Выделив какой либо элемент, являющийся

HTML-

документом, можно перейти к его редактированию на правой панели окна программы. Для того щелкните на данном элементе правой кнопкой мыши и выберите в контекстном меню команду Edit (Правка). Схему сайта можно просмотреть как в виде диаграммы, так и в виде обычного дерева каталогов. Для переключения с одного вида на другой, нужно щелкнуть правой кнопкой мыши и любом месте вкладки Site View (Схема сайта), выбрать в контекстном меню пункт View Style (Метод просмотра) и установить флажок либо Tree (Дерево), либо Chart (Диаграмма).



Сортировка таблицы


Теперь давайте осуществим сортировку списка книг. Добавим для начала две кнопки — для сортировки по алфавиту, соответственно, авторов и названий книг:

<INPUT TYPE="button"VALUE="Сортировать по автору" onClick="sort_auth()">

<INPUT TYPE="button"VALUE="Сортировать по названию" onClick="sort_name()">

Теперь напишем сами функции сортировки. Для этого нам подойдет чудес-ное свойство элементоуправления Tabular Data, которое называется SortColumn. В качестве его значения нужно указать поле, значения которого нужно сортировать. Для сортировки по фамилиям авторов в данном случае сле-дует указать поле Author, а для сортировки по названиям книг — поле Name. После этого нужно не забыть применить метод Reset(), чтобы заново “перерисовать” весь список:

function sort_auth() { hudlit.SortColumn="Author"; hudlit.Reset() ;

} . function sort_name() { hudlit.SortColumn="Name" ; hudlit.Reset();

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

<OBJECT>

элемента управле-ния Tabular Data:

<PARAM NAME="SortColumn" VALUE="Author">

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

Давайте посмотрим на текст получившейся страницы.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Электронная библиотека</TITLЕ>

<STYLE> BODY { background-color: #F4FFEF;

color: #182F1A; font-family: sans-serif; font-size: 120%;


} </STYLE> <SCRIPT LANGUAGE""JavaScript" TYPE="text/javascript">

function auth() { document.all.book.value="";

hudlit.Filter="Author="+document.all.auth.value;

hudlit.Reset () ;

} function bookname() {

document.all.auth.selectedlndex=0;

hudlit.Filter="Name="+document.all.book.value;

hudlit.Reset (); } function sort auth()

{ hudlit.SortColumn="Author";

hudlit.Reset () ;

}

function sort_name()

{ hudlit.SortColumn="Name";

hudlit.Reset() ;

//-->

</SCRIPT>

</HEAD>

<BODY>

<Н1>Художественная литература</Н1>

<INPUT TYPE="button" VALUE=" Сортировать по автору" onClick="sort_auth()">

<INPUT TYPE="button" VALUE="Сортировать по названию" onClick="sort_name()">

<BR><BR>

Выберите автора:

<SELECT NAME="auth" onChange="auth ()">

<OPTION VALUE="">Bce

<OPTION VALUE="Дюма">Дюма

<OPTION VALUE="Достоевский">Тостоевский

<OPTION VALUE ="Толстой">Толстой ;</SELECT>

<BR><BR> Или введите название книги:

<INPUT TYPE="text" NAME="book" SIZE="15" MAXLENGTH="25">

<INPUT TYPE="button" NAME="search" VALUE="Поиск" onClick="bookname()">

<BR><BR>

<OBJECT ID="hudlit" CLASSID="clsid:333C7BC4-460F-11DO-BC04-0080C7055A83" B0RDER="0" ,WIDTH="0" HEIGHT="0">

<PARAM NAME="DataURL" VALUE="books.txt">

<PARAM NAME="UseHeader" VALUE="True"> </OBJECT>

<TABLE DATASRC="#hudlit"> <TR>

<TD><SPAN DATAFLD="Author"></SPAN>, &laquo;

<SPAN DATAFLD="Name"></SPAN>&raquo;,



<SPAN DATAFLD="Size"> </SPAN>Snbsp;кбайт.

<SPAN DATAFLD="File" DATAFORMATAS="html"> </SPAN></TD>

</TR> </TABLE>

</BODY>

</HTML>

Результат показан на рис. 9.2. Конечно, это очень простой пример, который хочется еще улучшить. Например, перед поиском введенного пользователем названии книги хорошо бы сначала удалить лишние пробелы и кавычки, а если введенное название не найдено, то вывести сообщение oб этом. Можно использовать файл базы данных для построения нескольких различных страниц и т. д. Однако приведенный пример уже дает некоторое представление о возможностях элемента Tabular Data. Читателям, заинтересовавшимся использованием элементов управления в Internet Explorer, можно рекомендовать обратиться к специальной литературе по этой теме.



Рис. 9.2. Соративовка данных


Создание графических карт ссылок


Для создания графической карты ссылок служит кнопка New Image Map (Создать изображение-карту) на верхней панели инструментов. Она открывает диалоговое окно, в котором можно выбрать какое-либо изображение, уже имеющееся на странице, или загрузить новое. После этого открывается окно редактора графической карты ссылок (Image Map Editor)

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

инструмента Стрелка можно легко отредактировать местоположение задан ных областей. После определения каждой области автоматически откры вается окно, в котором выбирают URL-адреса гиперссылок (атрибут HREF= тега <AREA>). Таким образом, создание графической карты ссылок пре вращается из сложного и утомительного занятия (каким оно всегда раньше считалось) в легкую и приятную процедуру.

Итак, мы рассмотрели некоторые полезные возможности панели редак тирования. Однако помимо вкладки Edit (Правка) на ней имеются еще две вкладки.



Создание ячеек таблицы


Теперь нужно определить сами ячейки. Если посмотреть на рис. 8.4, то может показаться, что их меньше, чем на самом деле. В процессе опреде-ления ячеек бывает удобно временно установить в теге

<TABLE>

атрибут BORDER=. В этом случае все границы между ячейками будут видимы.

Кик видно из рисунка, четвертая строка этой таблицы — единственная, где определены все пять столбцов, но этого уже достаточно. Тем не менее, для верности лучше поместить прозрачный рисунок во всех “пустых” ячейках таблицы. В третьей и пятой строках таблицы объединены в столбцов. Эти строки используются в качестве вертикального отступи между графическими гиперссылками. Здесь помещен прозрачный рису нок, “растянутый” в высоту:

<TR><TD COLSPAN="5">

<IMG SRC="Images/diafanol. gif" WIDTH="4" HEIGHT="20" BORDER="0" ALT=""></TD></TR>

Как видите, высота этой строки равна 20 пикселам. Пустые ячейки в осталь ных строках используются для задания ширины столбцов, например, так.

<TD><IMG SRC="Images/diafanol.gif" WIDTH="20" HEIGHT="3"

BORDER="0" ALT=""></TD>

 

Здесь помещен прозрачный рисунок, “растянутый” по горизонтали. Остальные “пустые” ячейки также заполнены прозрачными рисунками. размеры которых проставлены, исходя из того, что ширина каждого рисунка гиперссылки равна 120 пикселам, а ширина всех отступов — 20 пикселе и

Давайте окинем взглядом весь текст этой страницы.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.О Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Электронная библиотека</ТIТLЕ>

<STYLE> BODY { background-color: #FOE7F1;

} H2 { text-align: center;

} TD { font-family: MS Comic Sans, sans-serif;

text-align: center; }

</STYLE>

</HEAD>

<BODY>

<TABLE WIDTH="99%" BORDER="0" CELLSPACING="0" CELLPADDING="0">


<TR><TD СOLSPAN="5">

<Н2>Электронная библиотека</Н1>

</ТD>

</ТR>

<TR>

<TD><IMG SRC="Images/hudlit.gif" WIDTH="120" HEIGHT="120" BORDER="0" ALT="Xyдoжecтвeннaя">

<BR>Xyдoжecтвeннaя литература </TD>

<TD COLSPAN="4"><IMG SRC="Images/diafanol.gif" WIDTH="280" HEIGHT="3" BORDER="0" ALT=""></TD>

</TR>

<TR><TD COLSPAN="5">

<IMG SRC="Images/diafanol.gif" WIDTH="4" HEIGHT="20" BORDER="0" ALT=""></TD></TR>

<TR><TD>

<IMG SRC="Images/diafanol.gif" WIDTH="120" HEIGHT="3"

BORDER="0" ALT=""></TD><TD>

<IMG SRC="Images/diafanol.gif" WIDTH="20" HEIGHT="3" BORDER="0" ALT=""></TD><TD>

<IMG SRC="Images/naulit.gif" WIDTH="120" HEIGHT="120" BORDER="0" ALT="Hayчнaя"><BR>Hayчнaя литература</ТD><ТD>

<IМG SRC="Images/diafanol.gif" WIDTH="20" HEIGHT="3"BORDER="0" ALT=""></TD><TD>

<IMG SRC="Images/diafanol.gif" WIDTH="120" HEIGHT="3" BORDER="0" ALT=""></TD></TR>

<TR><TD COLSPAN="5">

<IMG SRC="Images/diafanol.gif" WIDTH="4" HEIGHT="20" BORDER="0" ALT=""></TD></TR>

<TR><TD COLSPAN="4">

<IMG SRC="Images/diafanol.gif" WIDTH="280" HEIGHT="3" BORDER="0" ALT=""></TD><TD>

<IMG SRC="Images/detlit.gif" WIDTH="120" HEIGHT="120" BORDER="0" ALT=""><BR>Детская литература</ТD></ТR>

</TABLE>

</HTML>

В этом примере не поставлены сами гиперссылки, т. е. теги <А>, поскольку ни самой библиотеки, ни ее разделов пока что не существует. Добавить их не составит труда.

Если вы будете применять такую технологию при создании страничек, то перед написанием кода таблицы набросайте ее схему (с границами) хотя бы просто карандашом на бумаге. После этого написать код становится очень просто, поскольку в голове возникает ясная и наглядная картина будущей таблицы.

Однако, на наш взгляд, для решения подобных задач удобнее использовать абсолютное (и относительное) позиционирование элементов. При таком подходе, кстати, легче организовать и внутристраничную навигацию. Об этом пойдет речь в следующем разделе.


Создание таблиц


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

HTML.

В результате может получиться вполне симпатичная табличка, как на рис. 2.1

2.

Рис. 2.1

2

. Таблица, созданная простейшими средствами

HTML

Как же сделана эта таблица? Для того чтобы это понять, давайте рассмотрим сначала соответствующие средства

HTML.



Создание веб-страниц при помощи программы Allaire Homesite/Cold Fusion


Одним из самых замечательных программных продуктов, предназначенных для разработки веб-страниц, является программа Homesite, созданная компании Allaire. Множество доступных функций сочетаются здесь с исключительным удобством для пользователя. В этом разделе мы постараемся кратко рассказать о возможностях, которые предоставляет эта программа.

Однако прежде всего необходимо отметить, что использование программы Homesite подразумевает знание пользователем языка

HTML

(а также, по желанию, JavaScript и др.) Программа автоматизирует ввод кода, проверяет ошибки и т. д., но она не в силах помочь, если пользователь не представляет себе, что такое

HTML.

В этом разделе мы будем оперировать понятиями и тегами, значения которых поясняются в главах 2-8 этой книги. Поэтому, если вы сейчас еще не очень хорошо представляете, что означает тот или иной тег, не волнуйтесь — прочтите этот раздел бегло, а затем вернитесь к нему после прочтения всей книги (если, конечно, захотите использовать в своей работе программы Homesite/ColdFusion).

На момент написания этих строк последней версией программы Homesite является версия 4.5. На нее мы и будем ориентироваться в дальнейшем.

Итак, давайте начнем. Основное окно программы Homesite представлено на рис.

1.20. Как видите, оно разделено на две панели. Левая панель называется Resource Tab (Панель ресурсов) — она предназначена для различных вспомогательных функций. На правой панели (Панели редактирования) происходит собственно редактирование текста

HTML.

Сначала давайте рассмотрим левую панель (Resource Tab). На ней располагаются шесть вкладок, обозначенных следующими значками (слева направо): Files (Файлы), Projects (Проекты), Site View (Схема сайта), Snippets (Отрывки), Help (Справка) и Tag Inspector (Средство просмотра тегов). Если почему-либо образы значков кажутся неочевидными, их можно заменить на текстовые обозначения командой Options

>

Settings > General

>

Tab Style (Параметры

>

Установки

>

Общие

>

Стиль ярлыков вкладок).



Списки


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

Выбор возрастной категории можно организовать в виде раскрывающегося списка. Для создания такого списка используется тег

<SELECT>

. Между ним и его закрывающим тегом

</SELECT>

можно поместить несколько пунктов будущего списка. Каждый из них должен начинаться с тега

<OPTION>

. В данном случае мы можем написать так:

<SELECT NAME="Age" SIZE="1">

<OPTION VALUE="10">менее 20

<OPTION VALUE="20">20&ndash;30

<OPTION VALUE="30">30&ndash;40

<OPTION VALUE="40">40&ndash;50

<OPTION VALUE="50">50&ndash;60

<OPTION VALUE="60">6onee 60 </SELECT>

Рис. 7.1. Простейшая форма HTML

При этом на экране будет отображен раскрывающийся список, из которого пользователь может выбрать любой из пунктов. Значение атрибута VALUE= выбранного пункта будет передано на сервер при отправке данных формы.

Вы, вероятно, обратили внимание еще на один атрибут тега

<SELECT>

— атрибут SIZE=. Здесь его значение равно 1 (кстати, это значение определено по умолчанию, так что можно было этот атрибут и не указывать). Если указать значение, большее 1, то в окне броузера вместо раскрывающегося списка отобразится так называемый прокручиваемый список. На рис. 7.2 приведен пример прокручиваемого списка при атрибуте SIZE="3". Как видно, в данном случае в списке одновременно отображаются три строки (число одновременно отображаемых строк прокручиваемого списка и определяется с помощью атрибута S1ZE=). Если же надо дать пользователю возможность выбора сразу нескольких пунктов из списка, то в теге

<SELECT>

надо установить атрибут MULTIPLE=.

Рис. 7.2. Прокручиваемый список



Стили элементов


Таблица стилей обычно располагается в заголовке HTML-документа, в разделе

<HEAD>

. Она занимает место между тегами

<STYLE>

и

</STYLE>

. Синтаксис таблицы стилей таков. Вы пишете имя элемента HTML, для которого определяете стиль, а после него следует блок определения стиля, заключенный в фигурные скобки. Например, в нашем примере можно написать так:

<STYLE> BODY { background-color: #ВАВААО; color: rgb(29,29,24); }

</STYLE>

Пробелы здесь не имеют никакого значения, так же, как и переводы строк. После этого в самом тексте HTML-документа достаточно указать тег

<BODY>

, и к нему автоматически будут применены данные цвета фона и текста.

Пока что мы вроде бы не получили никакой видимой экономии, хотя скоро вы увидите, что имеет смысл располагать стилевые свойства

<BODY>

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

Н1,Н2 { text-align: center; }

и после этого просто указывать в документе теги

<Н1 >

или

<Н2>

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

Если вы помните, у нас еще оставались в теге

<BODY>

три “отмененных” атрибута: LINK=, ALINK= и VLINK=. Вместо них рекомендуется определить стили для различных псевдоклассов элемента

<А>.

Это делается так:

A:link,A:visited { color: #634438; } A:active { color: black; }

Как видите, для элемента

<А>

определены три псевдокласса (имена кото рых отделяются двоеточием): link — для гиперссылок, visited — для посе щенных гиперссылок и active — для активных. Кроме того, во второй версии CSS (CSS Level 2) для тега

<А>

определены еще псевдоклассы hover (гиперссылка, над которой находится указатель мыши) и focus (выбран

ная гиперссылка). Однако в броузере Internet Explorer версии 5 поддерживается только первый из них. Например, если написать

A:hover { color: white; }

то при наведении указателя мыши на ссылку она будет подсвечиваться белым цветом. Это уже похоже на динамическое взаимодействие с пользователем!'

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

HR { margin-top: 24px; width: 75%; }

и потом в текст документа вставлять только тег

<HR>

, и тогда, если не указано иное, линия получится такой, какой нужно.



Стили классов


Все это хорошо, конечно, но как быть дальше? Ведь в тексте нашего примера несколько раз (в данном случае два, но могло бы быть и гораздо больше!) определяется один и тот же стиль для текста эпиграфа, другой стиль для основного текста и третий для подписи к эпиграфу... Хорошо бы тоже определить их в таблице стилей, однако в нашем HTML--документе все они расположены внутри элементов

<DIV>

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

Итак, у нас должно быть три различных стилевых варианта для элемента

<DIV>

. В CSS они называются классами. Чтобы отличить эти элементы друг от друга, у них придется установить атрибут CLASS=, приблизительно так:

<DIV CLASS="epig">...</DIV> <DIV CLASS="pdps">...</DIV> <DIV CLASS="ab">...</DIV>

Имена классов выбираются произвольно. В данном случае мы образовали их от слов “эпиграф”, “подпись” и “абзац”. В таблице стилей эти классы можно определить так:

DIV.epig { text-align: justify; font-size: smaller; width: 130; }

DIV.pdps { font-style: italic;

text-align: right; }

DIV.ab { text-align: justify;

text-indent: 2em; }

Между прочим, другие элементы (причем практически все) также могут иметь атрибут CU\SS=. Если надо, чтобы определение класса было доступно всем элементам, его можно определить так:

pdps { font-style: italic;

text-align: right; }

То есть, при определении не указывается имя конкретного элемента

HTML,

а указывается только имя класса, которое в любом случае начинается с точки (но только в таблице стилей, а при обращении к классу в тексте документа точка не ставится). В данном примере мы определяли классы только для элемента <DIV>. Более того, в таком определении предполагается (то есть мы как бы помним), что элемент класса pdps будет вложен в элемент класса epig.
Хотя, с другой стороны, наше определение pdps годится не только для подписи под эпиграфом, но и для любой другой, если она вдруг потребуется.

Кстати, кроме стилевых свойств элементов

HTML

и классов, мы можем определять свойства так называемых

идентификаторов.

Дело в том, что у каждого элемента

HTML

может быть атрибут ID= — его уникальное имя в данном документе (этот атрибут играет большую роль при динамическом взаимодействии с пользователем, так что с ним нам еще придется не раз столкнуться). Если вы хотите определить в таблице стилей свойства для элемента, имеющего определенный идентификатор ID=, это можно сделать так:

#соо1 { color: white; background-color: black; )

Тогда элемент по имени cool (например

<DIV ID="cool">

) будет наделен указанными свойствами (в данном случае белым цветом символов на черном фоне). Только не забывайте, что в каждом HTML-документе каждый идентификатор ID= должен быть уникальным, то есть не может быть двух и более элементов с одинаковым значением атрибута ID=.

Ладно, это мы немного отвлеклись, так что давайте посмотрим на новый вариант странички Сергея Сергеева целиком.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLE>Домашняя страница Сергея Cepreeвa</TITLE>

<STYLE>

<!--

BODY { background-color: #BABAAO;

color: rgb(29,29,24);

}

H1,H2 { text-align: center;

} A:link,A:visited { color: #634438;

} A:active { color: black;

} HR { margin-top: 24px;

width: 75%; ) DIV.epig { text-align: justify;

font-size: smaller;

width: 130; } DIV.pdps { font-style: 'italic;

text-align: right;

} DIV.ab { text-align: justify;

text-indent: 2em; }

-->

</STYLE>

</HEAD>

<BODY> <Н1>Домашняя страница Сергея Сергеева</Н1>

<DIV STYLE="text-align: center;"><A HREF="#skazka">CKА3KА &1аquо;Иван-царевич и серый зaяц&raquo;</A>&nbsp;



<А HREF="#rasskaz">PaccKa3 &laquo;МОЛОТОK&raquo;</A>

</DIV>

<BR>

<DIV STYLE="font-size: larger;">

<SPAN STYLE="font-weight:

bold;">Сергей Сергеев</SPAN> Smdash; писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<ВR>

<ВR>

Некоторые его рассказы вы можете прочитать прямо здесь.</DIV>

<HR>

<Н2><А NAME="skazka">ИBAH-ЦAPEВИЧ И СЕРЫЙ ЗАЯЦ</А><ВR>

<SPAN STYLE="font-style: italic; ">CKА3KА</SPAN></H2>

<DIV STYLE="text-align: right

;">

<DIV CLASS="epig">

Ну, погоди!..

<DIV CLASS="pdps">(Из мультфильма)</DIV>

</DIV>

</DIV> <BR>

<DIV CLASS="аЬ">Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный. Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.</DIV>

<DIV CLASS="ab">Дoлгo ли, коротко ли, ...</DIV>

<DIV CLASS="ab">...И они жили долго и счастливо и умерли в один день.</DIV>

<HR>

<Н2><А NAME="rasskaz">МОЛOTOK</A>

<BR>

<SPAN STYLE="font-style: italic; ">paccкaз</SPAN>

</H2>

<DIV STYLE="text-align: right;">

<DIV CLASS="epig"> Мы кузнецы, и дух наш молод. <DIV CLASS="pdps">(Из песни)</DIV>

</DIV>

</DIV>

<BR>

<DIV CLASS="ab">Этo случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </DIV>

</BODY>

</HTML>

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


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

Наверное, вы обратили внимание на странные сочетания

<!--

и

-->

, которые появились в нашем примере около тегов

<STYLE>

. Вообще говоря, в такие символьные сочетания (это, кстати, тоже теги) в HTML-докумен-тах заключают комментарии. То есть все, что находится между этими тегами, игнорируется броузером. Но в данном случае мы пользуемся тем, что внутри STYLE -блока действуют законы синтаксиса не HTML, a CSS. Так что те броузеры, которые “понимают” тег

<STYLE>

и, следовательно, CSS, “поймут” и то, что в данном случае это не символы комментария, и проинтерпретируют таблицу стилей, как положено. А те броузеры (в основном, старые), которые CSS не понимают, воспримут содержимое таблицы стилей как комментарий. (Если не поставить теги комментариев, то эти броузеры, проигнорировав тег

<STYLE>

как непонятный им, скорее всего станут выводить на экран все содержимое таблицы стилей.) Таким же образом мы будем “обманывать” старые броузеры при использовании тега

<SCRIPT>.


Страница, управляемая при помощи мыши


Мы уже говорили о том, что одним из самых привлекательных нововведе ний HTML 4.0 является возможность динамически изменять страницы и реагировать на действия пользователя. Давайте рассмотрим, как такая реакция может осуществляться.

Помните, как в примерах Главы 4 мы изменяли цвет гиперссылки при наведении на нее мыши? Это происходило с помощью псевдокласса :hover. Однако этот псевдокласс пока что определен только для тега

<А>

. А как быть, если мы хотим изменить цвет обычного текста при наведении на него мыши?

Рассмотрим, как это делается. Допустим, мы написали небольшую тесто вую страницу.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТIТLЕ>Обработка событий мыши</ТIТLЕ>

</HEAD>

<BODY> Этот текст не изменит свой цвет. Этот текст изменит свой цвет, если навести на него мышь! Этот текст не изменит свой цвет.

</BODY>

</HTML>



Страница, управляемая с клавиатуры


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

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



Сжатие звука


Итак, звук записан и теперь его надо сжать. Кстати говоря, если вы его записывали программой Sound Forge, то можно, прямо не выходя из нее, сжать звук в формат RealAudio. Для этого дайте команду File > Save As (Файл > Сохранить как) — откроется диалоговое окно сохранения файла. В раскрывающемся списке Files of Type (Тип Файла) выберите тип RealNetworks G2 или Real Media для совместимости со старыми версиями — в этом случае качество звучания будет чуть хуже. После щелчка на кнопке Save (Сохранить) откроется окно, в котором можно выбрать параметры сжатия в виде описания. Если же использовать кнопку Advanced (Дополнительно), то можно выбрать степень сжатия в явном виде.

Если в вашей системе установлен модуль кодирования МРЗ, то вы сможете сжать файл с помощью МРЗ-алгоритма тоже непосредственно из программы Sound Forge. Для этого выберите в раскрывающемся списке Files of Type (Тип Файла) пункт Wave, а в раскрывающемся списке Format (Формат) - пункт MPEG Layer-3. При этом можно задать степень сжатия с помощью раскрывающегося списка Attributes (Характеристики). Однако учтите, что при этом будет записан файл, сжатый алгоритмом МРЗ, но в формате WAVE.



Сжатие звуковых файлов


Как уже говорилось выше, несжатые звуковые данные CD-качества занимают приблизительно 10 Мбайт на минуту звучания. Поэтому были разра ботаны специальные алгоритмы сжатия звуковых файлов. К сожалению, все они обладают одним и тем же недостатком: чем сильнее снижается объем файла звукозаписи, тем хуже становится ее качество. Поэтому приходится балансировать, выбирая между качеством записи и размером файла. На многих веб-страницах музыкальной тематики даже предлагаются несколько вариантов одного и того же музыкального фрагмента — более качественный для загрузки через JSZW-линию и несколько менее качественных для загрузки по модемным линиям с различной скоростью.

Наиболее популярны на сегодняшний день три формата сжатия звуковых файлов: RealAudio, MPEG 1 Layer 3 и TwinVQ.

Формат RealAudio был разработан фирмой RealNetworks. Это самый ран ний из форматов сжатия звукозаписи, и потому он наиболее распростра нен в Интернете. В настоящее время он поддерживает сжатие для потока (скорости загрузки) от 5 до 96 килобит в секунду. Низкие значения этого параметра (от 5 до 16 Кбит/с) предназначены для медленных модемов. Их предпочтительнее использовать лишь для речевых записей, поскольку при скорости потока 16 Кбит/с максимальная воспроизводимая частота звука не превышает 8 КГц, то есть при прослушивании пользователь практически не услышит высоких частот, а при более сильном сжатии (до 5 Кбит/с) о каком-то адекватном восприятии вообще говорить не приходится. Для сжатия музыки лучше использовать скорость потока не менее 32 Кбит/с, что дает вполне приемлемые результаты для монофрагментов.

Вы можете спросить, а почему это степень сжатия мы вдруг стали измерять в единицах величины потока (скорости загрузки)? На самом деле это имеет смысл! Дело в том, что главной проблемой использования звука в Интернете было то, что пользователь просто уставал ждать, пока загрузится большой файл — ведь воспроизведение его могло начинаться только по окончании полной загрузки. Компания RealNetworks предложила нов шество, называемое потоковым методом воспроизведения звуковых (а впоследствии и видео-) файлов. При использовании этого метода воспроизведение может начаться почти сразу же после начала загрузки файла. Пока одна часть файла загружается, другая уже воспроизводится!

В этом случае очень важно рассчитать именно скорость загрузки. Ведь необходимо, чтобы пока один фрагмент воспроизводится, следующий успел загрузиться, иначе вся технология теряет смысл. Разные модемные линии имеют разную скорость потока данных, поэтому для них, соответственно, необходима разная степень сжатия звуковых файлов. Чтобы избавить пользователя от вычислений, степень сжатия файлов сразу стали обозна чать через соответствующую скорость потока данных.

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



Теги HTML


Пользователь увидит эту страничку так, как показано на рис. 1.2. Это уже что-то, хотя и не слишком привлекательно: во-первых, исчезло форматирование текста (абзацы), во-вторых, — как-то скучно смотрится. Кроме того, есть такие строгие броузеры, которые вообще не отобразят этот текст, если не увидят в нем подтверждение того, что он написан на языке HTML (языке гипертекстовой разметки, на котором и пишутся веб-страницы). Расширение .html такой броузер может посчитать недостаточным подтверждением, поэтому придется написать несколько дополнительных строк:

<HTML>

<BODY>

Домашняя страница Сергея Сергеева

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

Слова, заключенные в угловые скобки, являются служебными словами языка HTML. Их принято называть тегами (tags). Теги никогда не отображаются при просмотре страницы — они служат для управления оформлением.

Существуют разные транскрипции слова browser, означающего просто программу просмотра веб-странип. Некоторые пишут “броузер”, а другие — “браузер”. Мы будем придерживаться второго варианта.

Тег

<HTML>

, который вы видите в первой строке, означает, что наш текст действительно написан на языке HTML. Большинство тегов языка HTML — парные. Они обязательно требует присутствия закрывающего тега. Например, в этом примере в первой строке стоит открывающий тег

<HTML>

, а в последней — закрывающий тег </HTML>. Все, что расположено между ними, считается .HTML-документом.

В языке HTML совершенно не имеет значения, строчными или прописными буквами записаны теги. Можно написать

</HTML>

или

<html>

— для броузера это одно и то же. Однако принято писать теги HTML прописными буквами, чтобы они лучше выделялись на фоне основного текста.

В рассмотренном примере вы видите еще один тег —

<BODY>

. Все, что расположено между ним и его закрывающим тегом (

</BODY>


), считается “телом” документа и отображается на экране. HTML,-документы, помимо “тела”, обычно содержат еще и заголовок, в котором заключена различная служебная информация. Заголовок располагается между тегами

<HEAD>

и

</HEAD>

. Например, следующий код будет отображен в броузере так, как показано на рис. 1.3.

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева </TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева.

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>



Рис. 1.3. Простейшая страничка: текст и заголовок

Обратите внимание на то, что в заголовке окна броузера также появились слова “Домашняя страница Сергея Сергеева”. Это произошло потому, что в разделе заголовка

<HEAD>

мы поместили этот текст между тегами

<TITLE>

и

</TITLE>

Теперь вспомним о том, что при отображении в броузере наш текст потерял форматирование. Это произошло потому, что броузер игнорирует перевод строки. Однако если вы все же хотите видеть свой текст с таким же разбиением на строки, какое было в редакторе Блокнот, нужно заключить его между тегами <PRE> и </PRE>:

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева</ТIТLЕ>

</HEAD>

<BODY>

<PRE>

Домашняя страница Сергея Сергеева

Сергей Сергеев - писатель-юморист, автор 20 рассказов.

В жизни большой любитель собак и компьютерных игр.

</PRE>

</BODY>

</HTML>

Результат показан на рис. 1.4. Уже лучше, не правда ли? Однако есть два момента, из-за которых мы не советовали бы без крайней необходимости употреблять тег <PRE>. Во-первых, как видно из рисунка, текст теперь отображается так называемым моноширинным шрифтом, похожим на шрифт пишущей машинки. Большинство броузеров отображают текст,



Рис. 1.4. Страничка, отформатированная с помощью тега



<PRE>

заключенный между тегами

<PRE>

и

</PRE>

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

<PRE>

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

<PRE>

не позволяет этого сделать, и если строка “вылезет” за пределы окна просмотра, то для ее чтения придется воспользоваться горизонтальной полосой прокрутки, что неудобно и обычно раздражает. Другими словами, если вы используете тег

<PRE>

, вам придется специально заботиться о длине строк, а это затруднительно, поскольку никто заранее не знает, какой размер окна броузера будет у пользователя. Без тега

<PRE>

броузер позаботится об удобстве просмотра сам (это будет проиллюстрировано далее на рис. 1.6).

Для форматирования текста существует множество специальных тегов. Сейчас рассмотрим самый простой из них — тег

<BR>

. В том месте, где он стоит, происходит принудительный переход на новую строку. (Причем в исходной записи можно продолжать текст на этой же строке — это не имеет значения.) Тег

<BR>

не имеет закрывающего парного тега, он употребляется сам по себе. Вот как сохранить наше форматирование текста без использования тега

<PRE>

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева.</TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева.

<BR>

<BR>

Сергей Сергеев - писатель-юморист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

Результат показан на рис. 1.5. Как видите, форматирование текста сохранено, шрифт остался пропорциональным и не превратился в моноширинный, а кроме того, если пользователь почему-либо будет просматривать страничку в очень узком окне, он все равно увидит весь текст (рис. 1.6).



И, наконец, еще одна деталь: иногда броузеры или другие программы обработки требуют, чтобы в начале HTML-документа обязательно стоял служебный тег

<!DOCTYPE>

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



рuc. 1.5. Страничка с простейшим



Рис. 1.6. Та же страничка в форматированием текста узком окне броузера

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТIТLЕ>Домашняя страница Сергея Сергеева </TITLE>

</HEAD>

<BODY>

Домашняя страница Сергея Сергеева <BR><BR>

Сергей Сергеев - писатель-юморист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.

</BODY>

</HTML>

В данном случае в первой строке стоит указание, что в документе использована версия 4.0 языка HTML. В дальнейшем мы будем ориентироваться именно на нее, хотя приведенный выше пример с таким же успехом мог бы быть написан и с использованием версии 3.2, и даже более ранней. Однако HTML 4.0 предоставляет такие возможности создания веб-страниц, которых не было в предыдущих версиях. И хотя некоторые старые программы просмотра не в силах адекватно отобразить страницы, написанные с использованием особенностей новой версии, все же подавляющее большинство читателей сегодня пользуются новыми броузерами. Мы будем ориентироваться именно на них.


Текстовая база данных


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

Толстой,Анна Каренина,305,<А HREF="anna.ziр">загрузить</А>

Как видите, заполнение базы данных вполне можно поручить любому человеку, умеющему использовать компьютер как пишущую машинку. (В принципе, можно избавить его и от необходимости писать страшную конструкцию

<А HREF>

.) В начале файла базы данных напишем заголовок каждого поля. Вот что у нас получится:

Author,Name,Size:INT, File Дюма,Три мушкетера,250

<A HREF="trim.zip">3arpyзить</A> Дюма,Десять лет спустя,198,<А HREF="deslet.zip"> загрузить </А> Дюма,Двадцать лет спустя,170,

<А HREF="dvlet.zip"> загрузить </А> Толстой/Война и мир,1045,

<А HREF="vojna.rar"> загрузить </А> Толстой,Анна Каренина,305,<А HREF="anna.zip"> загрузить </А> Достоевский,Идиот,560,

<А HREF="idiot.zip"> загрузить </А>

Достоевский,Преступление и наказание,710,

<А HREF="prest.rar"> загрузить </А>

Достоевский,Двойник,432,

<А HREF="doppel.zip"> загрузить </А>

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

INT

Теперь давайте создадим саму веб-страницу. Сначала, как обычно, напи-шем заголовок и определим стиль вывода на экран:

<ТIТLЕ>Электронная библиотека</ТIТLЕ>

<STYLE> BODY { background-color: #F4FFEF;

color: #182F1A;

font-family: sans-serif; font-size: 120%;

} </STYLE>

</HEAD>

<BODY>

<Н1>Художественная литература</Н1>



Учет раскладки клавиатуры


Теперь надо подумать еще о том, что пользователь может забыть переклю- читься на русскую раскладку клавиатуры. Давайте не будем заставлять его это делать. Поскольку мы знаем, что на одной клавише с русской бук вой а расположена буква f, на одной клавише с б — знак < и т. д., мы можем осуществить проверку не только кодов букв а, б, в, г, д, е, но и кодов сим волов f, <, d, u, I, t. Можно написать, например, так: case 1072: case 102: document.all.BukvaA.scrolllntoViewO; break; case 1073: case 44:

document.all.BukvaB.scrollIntoView() ; break;

В этом случае прокрутка к букве а осуществится, даже если пользователь нажмет клавишу с буквой а или f, забыв переключиться на русскую рас-кладку клавиатуры. Аналогично можно осуществить прокрутку и к дру- им буквам. Чтобы при нажатии какой-нибудь иной клавиши вернуться началу файла, можно присвоить это возвращение случаю “default”:

default”: document.all.Top.scrollIntoView(); break;

Вот, собственно говоря, и все. Но чтобы изучить еще некоторые обработчики событий, давайте добавим еще эффект уменьшения яркости текста во время нажатия клавиши. Так обращают внимание пользователя на то, что “что-то происходит” (а именно: прокрутка). Для этого нужно использо-вать обработчики событий, реагирующие раздельно на нажатие и на отпускание клавиши. Они называются, соответственно: onKeyDown и onKeyUp:

<BODY onKeyPress="press ()" onKeyDown="this.style.color='gray'" onKeyUp="this style.color='black'">

Теперь во время нажатия на клавишу цвет текста изменится на серый, а после отпускания клавиши — обратно на черный. Как видите, ничего сложного.



Учет различий между броузерами


Такие вопросы обычно решаются не просто. Но в данном случае мы можем осуществить проверку версии броузера и, в зависимости от ее результата, присвоить переменной textl либо значение document.all.textl, либо значение document.getElementByld("text1"). А затем в функциях замены цвета просто подставлять эту переменную. То же самое можно проделать и с переменной text2. Только нужно не забыть заранее определить эти переменные:

var text1, text2; function brws()

{ if (navigator.appName!="Net scape")

{ textl=document.all.textl; text2=document.all.text2 ;

} else { textl=document.getElementById("textl") ;

text2=document.getElementById("text2"); } }

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

<BODY>

обработчик событий, реагирующий на загрузку элемента. Он называется onLoad:

<BODY onLoad="brws( )">

Посмотрим, что у нас получается в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transional//EN">

<HTML>

<HEAD>

<TITLE>06pa6oткa событий мыши (1Е4, NN6)</TITLE>

<SCRIPT LANGUAGE="JavaScript">

var textl, text2; function brws()

{ if (navigator.appName!="Netscape") ( textl=document.all.textl; text2=document.all.text2;

} else { textl=document.getElementById("textl") ; text2=document.getElementById("text2") ;

} } function change () { textl.style.color="red"; text2.style.color="green";

}

function change2() { textl.style.color="black"; text2. style. color="blacl<";

} //-->

</SCRIPT>

</HEAD>

<BODY onLoad="brws()"> Этот текст не изменит свой цвет.

<DIV !D="textl" onMouseOver="change() " onMouseOut="change2()">

Этот текст изменит свой цвет, если

навести на него мышь!

</DIV> <DIV !D="text2">Этот текст изменит свой цвет, если мышь навести на вторую строку!</DIV>


</BODY>

</HTML>

Результат можно увидеть на рис. 7.5. Теперь этот пример работает и в броузере Internet Explorer, и в броузере Netscape 6. Конечно, хотелось бы создавать такие страницы, которые бы работали по крайней мере в этих двух броузерах, потому что в Netscape версии 4 поддержка динамических страниц вообще очень слабая. Однако это не всегда возможно. В этой книге в дальнейшем все примеры будут ориентированы на броузер Internet Explorer версии 4 и выше (если специально не оговорено обратное).



Рис. 7.5. Страница, на которой цвет строк может изменяться

Кнопки, влияющие на вид страницы

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

Для начала в соответствии с требованиями HTML 4.0 заменим атрибуты BGCOLOR= и BACKGROUND= тега

<BODY>

на соответствующие стилевые свойства:

<STYLE> BODY { background-color: #BFFFBF;

background-image: url("Images/gradi.jpg"); }

</STYLE>

Что же касается тега

<BODY>

, то ему желательно присвоить имя для облегчения доступа к его свойствам:

<BODY ID="doc">

Теперь добавим сверху две кнопки: одну для выключения фонового рисунка, а другую — для смены цвета фона на белый:

<DIV ALIGN="center"> <INPUT TYPE="button" VALUE="Убрать фоновый рисунок">

<INPUT TYPE="button" VALUE="Сделать фон белым"> </DIV>

Кнопки созданы, но пока при их нажатии ничего не происходит. Нам надо написать функцию, убирающую фоновый рисунок. Для этого нужно всего лишь стилевому свойству background-image присвоить значение none:



function noBg() { document.all.doc.style.backgroundlmage='none'; }

Обратите внимание на то, что в тексте на языке JavaScript (а не на языке CSS) нужно обязательно преобразовать название стилевого свойства с дефисом, как объяснялось выше.

Теперь нужно сделать так, чтобы наша функция noBg() выполнялась при щелчке мыши на первой из кнопок. Для этого надо в соответствующий тег кнопки добавить обработчик событий, реагирующий на щелчок мыши. Он называется onClick:

<INPUT TYPE="button" VALUE="y6paть фоновый рисунок" onClick="noBg ()">

Аналогично создадим функцию для смены цвета фона на белый:

function colChangeO ( document.all.doc.stylе.backgroundColor='white'; } и добавим ко второй кнопке обработчик события onClick:

<INPUT TYPE="button" VALUE="Cделать фон белым" onClick="colChange()">

Если теперь открыть эту страницу в броузере, то при нажатии на кнопку Убрать фоновый рисунок градиентный фоновый перелив исчезнет, уступив место зеленоватому цвету, а при нажатии на кнопку Сделать фон белым фон страницы действительно станет белым.

Однако неплохо бы дать пользователю и возможность обратной смены цвета и включения градиента. Он, конечно, может для этого нажать в броузере кнопку Обновить, однако рассчитывать на это некорректно, да и нс всякий пользователь сразу сообразит это сделать. Поэтому давайте при выключении фонового рисунка сменим надпись на кнопке. Для этого желательно дать кнопкам имена, например вот так:

<INPUT TYPE="button" NAME="buttl" VALUE="Убрать фоновый рисунок" onClick="noBg()">

<INPUT TYPE="button" NAME="butt2"VALUE="Сделать фон белым" onClick="colChange()">

Можно было, разумеется, использовать и атрибут ID= вместо NAME=. Для того чтобы изменить надпись на первой кнопке, достаточно изменить значение ее атрибута VALUE=:

document.all.butti.value='Вернуть фоновый рисунок';



Теперь давайте подумаем, как нам переделать функцию поВд(). Ведь она должна убирать фоновый рисунок, если он есть, и включать его, если его нет. Одновременно нужно соответствующим образом изменять надпись на кнопке. Следовательно, нужно сначала проверить, есть ли фоновый рисунок:

function noBg() { if (document.all.doc.style.backgroundlmage="none") { document.all.doc.style.backgroundlmage='none' ;

document.all.butti.value='Вернуть фоновый рисунок';

} else { document.all.doc.style.backgroundlmage="url('Images/gradi.jpg')"'; document.all.butti.values'Убрать фоновый рисунок'; } }

В первой строке функции мы сравниваем значение стилевого свойства backgroundlmage со значением none, и если оно с ним не совпадает, то, значит, фоновый рисунок есть. В этом случае мы присваиваем этому спой ятву значение none и изменяем надпись на кнопке на Вернуть фоновый рису (нок. В противном же случае мы присваиваем свойству backgroundlmage значение, содержащее имя файла фонового рисунка, и изменяем надпись на кнопке на первоначальную.

Таким же способом мы переделываем функцию colChange(). Сначала проверим значение свойства backgroundColor, и, если оно не совпадает со значением white (белый), присвоим ему это значение, а в противном случае присвоим первоначальное значение #BFFFBF. Одновременно будем изме нять и надпись на второй кнопке: function colChange() { it (document.all.doc.style.backgroundColor!='white'){

document.all.doc.style.backgroundColor"'white' ;

document.all.butt2.value='Сделать фон зеленым';

}

else { document.all.doc.style.backgroundColor='#BFFFBF' ; document.all.butt2,value='Сделать фон белым'; } }

Теперь пользователь может с помощью первой кнопки включать и вык- лючать фоновый рисунок по желанию, а с помощью второй — переклю чать цвет фона с зеленоватого на белый и обратно. Однако остался еще один нерешенный вопрос. Дело в том, что если включен фоновый рису- нок, то переключение цвета фона не дает никакого видимого результат”, что может смутить пользователя.


Поэтому, пока включен фоновый рису нок, лучше вообще не давать возможности нажимать на вторую кнопку. Internet Explorer позволяет сделать ее недоступной с помощью атрибут DISABLED. Поскольку изначально фоновый рисунок включен, установим этот атрибут сразу же при создании второй кнопки:

<INPUT TYPE="button" NAME="butt2" VALUE="Сделать фон белым" DISABLED onClick="colChange()">

А в функцию noBg( ) следует включить сброс атрибута DISABLED для второй кнопки при выключении фонового рисунка и, соответственно, уста новку этого атрибута при включении фона:

function noBg() { if (document.all.doc.style.backgroundlmage!="none") {

document.all.doc.style.backgroundlmage='none'; document.all.butti.value='Вернуть фоновый рисунок'; document.all.butt2.disabled=false; } else { document.a 11.doc.style.backgroundlmage="url('Images/gradi.jpg')"; document.all.butti.value='Убрать фоновый рисунок'; document.all.butt2.disabled=true; } }

Вот теперь все становится на свои места. Пользователь сможет только тогда воспользоваться кнопкой для смены цвета фона, когда фоновый рисунок выключен. Можно было бы, конечно, и просто сделать вторую кнопку невидимой (с помощью стилевого свойства visibility), однако, на наш взгляд, это было бы менее наглядно. Давайте посмотрим, что у нас получилось в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN"> <HTML> <HEAD> <TITLE>CKА3KА</TITLE> <STYLE> BODY { background-color: #BFFFBF; background-image: url("Images/gradi.jpg") ; } </STYLE> <SCRIPT> <!--function noBg() { if (document.all.doc.style.backgroundlmage!="none") { document.all.doc.style,backgroundlmage='none' ; document.all.butti.value='Вернуть фоновый рисунок'; document.all.butt2.disabled=false; } else {

document.all.doc.style.backgroundlmage= "url('Images/gradl.jpg')";

document, all .buttl .value='Убрать фоновый рисунок'; document.all.butt2.disabled=true;



} }

function colChangef)

{ if (document.all.doc.style.backgroundColor!='white')

{ document.all.doc.style.backgroundColor='white' ;

document.all.butt2.value='Сделать фон зеленым'; }

else { document.all.doc.style.backgroundColor='#BFFFBF'' document.all.butt2.value='Сделать фон белым';

}

}

//-->

</SCRIPT>

</HEAD>

<BODY ID="doc"> <DIV ALIGN="center">

<INPUT TYPE="button" NAME-"buttl" VALUE="y6paть фоновый рисунок" onClick="noBg()">

<INPUT TYPE="button" NAME-"butt2 VALUE="Сделать фон белым" DISABLED onClick="colChange()">

</DIV>

<BR>

<DIV ALIGN="center">

<IMG SRC="Images/hr2.gif" WIDTH="508" HEIGHT="18" BORDER="0" ALT""></DIV>

<DIV ALIGN="center">

<IMG SRC="Images/skazk.gif" WIDTH="359" HEIGHT="150" BORDER="0" ALT="CKA3KA"><BR>

<H2> О ТОМ, КАК ИВАН-ДУРАК ПОСРАМИЛ ЦАРЯ ГOPOXA</H2></DIV>

<DIV ALIGN="justify"><IMG SRC="Images/bukvical.gif" WIDTH="121" HEIGHT="111" BORDER="0" ALIGN="LEFT" ALT="Д">

авным-давно жил- был на белом свете царь Горох. И были у него поля гороховые, и леса гороховые, и степи гороховые, и даже моря гороховые. Все было гороховым. И была у него дочь &mdash; царевна Горошина. Волосы у нее были зеленые, и глаза тоже зеленые, потому что с детства только на горох и смотрела. Но вообще-то она была писаной красавицей. Все придворные царские, и бояре, и пажи, и лакеи, и даже слуги и повара дворцовые были по уши влюблены в нее. Но была у царевны Горошины одна странность &mdash; любила она смотреть по ночам на далекую звезду Адырлетавру, которая светила в том царстве так ярко, что обычные люди на той стороне, где звезда была, даже окон в домах не делали. <BR><BR>



<FONT SIZE="+3">............................................

</FONT><BR><BR>

Тут и сказке конец, а кто слушал &mdash; молодец, ему пряник в награду и кило мармеладу.<BR>&nbsp;</DIV>

<DIV ALIGN="center"><IMG SRC=" Images/hr2 .gif" WIDTH="508" HEIGHT="18" BORDER="0" ALT=""></DIV>

</BODY>

</HTML>

Результат показан на рис. 7.6. Так страница будет выглядеть сразу после загрузки. Обратите внимание на то, что вторая кнопка изначально недоступна. Для красоты мы отделили наши кнопки от основного текста тем же разделителем, который использован в конце страницы.



Рис. 7.6. Веб-страница, на которой “бесполезная” в данный момент кнопка недоступна

Заметим, что приведенная выше страница будет работать только в Internet Explorer. Ее можно заставить работать и в Netscape 6 тем же способом, который мы применили в предыдущем примере — путем написания функции, присваивающей одной и той же переменной либо значение document.all, либо document.getElementByld, в зависимости от типа броузера:

var doc, butti, butt2; function brws(),

{ if (navigator.appName!""Netscape") ( buttl=dofc.ument .all. butti; butt2=docwnent.all.butt2; doc=docunysnt. all. doc;

}

else (

buttl=document.getElementById("buttl") ;

butt2=document.getElementById("butt2") ;

doc=document.getElementById("doc") ;

} }

Затем следует переписать функции noBg() и colChange( ), убрав из них обра щение document.all:

function noBg() { if (doc.style.backgroundlmage!="none")

{ doc.style.backgroundlmage='none' ; butti,value='Вернуть фоновый рисунок'; butt2.disabled=false;

}

else {

doc.style.backgroundlmage="url('Images/gradi.jpg')";

butti.value='Убрать фоновый рисунок'; butt2.disabled=true;

}

function colChange()

{ if (doc.style.backgroundColor!='white')



{ doc.style.backgroundColor='white' ; butt2.value='Сделать фон зеленым';

} else { doc.style.backgroundColor='#BFFFBF' ;

butt2.value='Сделать фон белым'; }

}

И, наконец, назначить выполнение функции brws() сразу после загрузки страницы:

<BODY ID="doc" onLoad="brws()">

Теперь наш код будет одинаково работать и в Internet Explorer 4+, и в Netscape 6. Что касается Netscape 4, то, если постараться, можно заставить эту стра ницу работать и там, но это будет довольно сложно. В Netscape 4 нельзя получить доступ непосредственно к свойствам тега

<BODY>

, однако броузер можно “обмануть”, использовав либо тег

<LAYER>

и коллекцию document.layers, либо свойства типа document.body.bgColor. Давайте лучше не будем этим заниматься, тем более что смотреть нашу страницу в Netscape 4 все равно можно, просто обе наши кнопки в нем вообще не отобразятся (этот броу зер не воспринимает теги

<INPUT>

вне элемента

<FORM>

).


Учет версии броузера


Теперь давайте рассмотрим простой пример. Предположим, что у нас уже имеются страницы, созданные специально для броузера Internet Explorer 4, Netscape 4 или Netscape 6. Мы хотим написать код, который бы определял тип броузера пользователя и, в зависимости от этого, загружала бы одну из наших страниц. Кроме того, он должен выдавать предупреждение, если обнаружит устаревший броузер (версии 3 и ниже).

Сначала давайте напишем такое предупреждение. Чтобы пользователь наверняка обратил на него внимание, можно использовать метод alert. Применяется он точно так же, как уже знакомый нам метод document.write, но при этом выводит текст не прямо на страницу, а в диалоговое окно. Пока пользователь не нажмет кнопку ОК, работа сценария не будет продолжена.

Как определить номер версии броузера? Для этого существует свойство navigator.appVersion. Однако его значением является не число (собственно номер версии), а целая строка. Например, если написать:

document.write(navigator.appVersion) ; то в броузере Internet Explorer 5 будет выдано такое сообщение:

4.0 (compatible; MSIE 5.0; Windows 98; DigExt)

Netscape и другие броузеры также выдают подобную длинную строку. Как же выделить из нее номер версии?

К счастью, первая цифра этой строки во всех броузерах указывает именно на номер версии (в Internet Explorer 5 на этом месте оставили цифру 4, чтобы подчеркнуть сходство этих версий.) Поскольку после этого номера стоит точка, то есть не цифра, его легко выделить из всей строки с помощью функции parselnt(). Она всегда выделяет целое число из строки, останавливаясь на первой не цифре.

В данном случае нам надо, если номер версии меньше 4, выдать предупреждающее диалоговое окно. Для проверки условия в JavaScript существует оператор if, после которого в скобках следует поставить условие. Поэтому мы можем написать так:

if (parseint(navigator.appVersion)<4)

alert("Вы используете старую версию броузера.\nВ ней страница может отображаться неправильно") ;


При этом метод alert будет выполнен только тогда, когда условие номер версии меньше 4 выполняется, а иначе он будет просто пропущен.

Вы, наверное, обратили внимание на странное сочетание \n. Оно используется в JavaScript в качестве специального символа, перевода строки. Вообще, в строках JavaScript символ обратной косой черты вместе со следующим за ним символом всегда означает специальный символ. В данном случае второе предложение в нашем диалоговом окне начнется с новой строки.

Хорошо, предупреждение мы написали, теперь нужно определить тип броузера. Для этого существует свойство navigator.appName. В Internet Explorer его значением является “Microsoft Internet Explorer”, а в броузерах компании Netscape — просто “Netscape”. Поскольку для каждого случая нам надо предусмотреть ряд действий, удобно использовать оператор switch (пере ключатель). Схематично его использование можно изобразить так:

switch (условие) { case "первый случай":

какие-то действия case "второй случай": какие-то действия

и т. д. default: действия во всех остальных случаях

В нашем примере условием является значение navigator.appName, а случаи могут быть такими: "Microsoft Internet Explorer" и "Netscape".

switch (navigator.appName) { case "Microsoft Internet Explorer": какие-то действия

case "Netscape": какие-то действия

действия во всех остальных случаях

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

Чтобы загрузить другую веб-страницу вместо данной, нужно присвоить новое значение свойству window.location.href. Например, если написать:

window.location.href = "msie4.html";

то текущая страница будет заменена в окне броузера на страницу msie4.html.


Давайте перед загрузкой новой страницы создадим соответствующее сообщение:

document-write ("Сейчас будет загружена страница для Internet Explorer 4") ;

setTimeout("window.local ion.href = 'msie4.html'", 3000);

При этом нам пришлось использовать функцию setTimeout, чтобы пользователь успел увидеть нашу надпись.

Поскольку на этом действия, предусмотренные для данного случая, закан- чиваются, нужно выйти из блока switch с помощью оператора break. После этого можно приступать к обработке других случаев.

Если тип броузера определился как Netscape, нам нужно опять смотреть его версию. Мы можем использовать для этого оператор if...else:

if (parseint(navigator.appversion)<=4)

{ document.write ("Сейчас будет загружена страница для Netscape 4");

setTimeout("window, location.href = 'nn4.html'", 3000); } else

{ document.write ("Сейчас будет загружена страница для Netscape 6") ;

setTimeout("window.location.href = 'nn6.html'", 3000); } Если условие parselnt(navigator.appversion)<=4

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

Кроме того, нужно предусмотреть действия для всех остальных случаев. Правда, таких случаев будет немного, поскольку многие броузеры (например Opera) любят представляться как Netscape. Однако предусмотреть такие действия все равно надо. Можно, например, предложить пользователю вручную выбрать нужную страницу:

alert ("Вы используете неизвестный нам тип броузера. \пСейчас вам будет предложено выбрать версию страницы, которую следует загрузить");

document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>");

document.write ("<A HREF='nn4.html'>Страница для Netscape 4 </A><BR>") ;

document.write ("<A HREF='nn6.html'>Страница для Netscape 6 </A>");



Итак, теперь посмотрим, что же у нас получается в целом:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD> <ТIТLЕ>Автоматический выбор нужной версии cтpaницы</TITLE>

</HEAD>

<BODY> <SCRIPT> < ! -- if (parseint(navigator.appVersion)<4)

alert("Вы используете старую версию броузера.\ nВ ней страница может отображаться неправильно") ;

switch (navigator.appName)

case "Microsoft Internet Explorer":

document.write ("Сейчас будет загружена страница для Internet Explorer 4");

setTimeout ("window.location.href = 'msie4.html'", 3000); break; case "Netscape": if (parseint(navigator.appversion)<=4)

{ document.write ("Сейчас будет загружена страница для Netscape 4") ;

setTimeout("window.location.href = 'nn4.html'", 3000);

} else

{ document.write ("Сейчас будет загружена страница для Netscape 6");

setTimeout("window.location.href = 'nn6.html'", 3000);

} break;

default:

alert ("Вы используете неизвестный нам тип броузера.><nСейчас вам будет предложено выбрать версию страницы, которую следует загрузить");

document.write ("<A HREF='msie4.html'>Страница для Internet Explorer 4</A><BR>") ;

document.write ("<A HREF='nn4.html'>Страница для Netscape 4</A><BR>") ;

document.write ("<A HREF='nn6.html>Страница для Netscape 6</A>");

} //—> </SCRIPT>

</BODY>

</HTML>

Результат просмотра этой страницы зависит от броузера. На рис. 6.3 изображено предупреждение, которое получит пользователь при просмотре этой страницы в броузере Internet Explorer.



Рис. 6.3. Использование условной переадресации и временной задержки

Таблица умножения

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


Теперь рассмотрим еще один очень простой пример, который демонстрирует, как можно иногда сократить себе труд с помощью языка JavaScript, а заодно рассмотрим оператор цикла for.

Допустим, нам потребовалось представить таблицу умножения. Конечно, можно вручную написать каждую ее строку:

<TABLE>

<TR>

<TD>2&times;2=4</TD>

<TD>3&times;2=6</TD>

<TD>4&times;2=8</TD>

И Т.Д.

(Кстати, специальный символ &times; означает знак умножения.) Это способ достаточно долгий и нудный, кроме того, легко можно допустить случайную ошибку и не заметить ее. Давайте попробуем сгенерировать таблицу прямо “на ходу”, используя средства JavaScript. Teг <TABLE> можно вынести за пределы сценария. Далее, нужно сформировать некоторое количество строк (традиционно равное количеству вариантов второго множителя, который обычно принимает значения от 2 до 10). Можно этот множитель занести в переменную (назовем ее “I”) и написать:

for (i=2; i<=10; i++)

{ document.write ("<TR>"); document.write ("</TR>") ;

}

Выражение в скобках после оператора цикла for означает следующее: • начальное значение переменной — 2;

условие выполнения цикла — переменная должна быть меньше или равна 10;

на каждом шаге переменная увеличивается на 1 (обозначение “++” означает увеличение на единицу, а “- -” уменьшение на единицу.)

Если сейчас запустить этот цикл, то в окне броузера ничего не отобразится, поскольку пока нет тегов ячеек таблицы (

<TD>

). Поскольку в каждой строке должно быть столько ячеек, сколько значений принимает первый множитель (занесем его в переменную “j”), организуем между записью тегов

<TR>

и

</TR>

еще один цикл:

for (j=2; j<10; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>") ;

Здесь условием выхода из цикла является j<10, а не j<=10, поскольку традиционно первый множитель в таблице умножения не превышает 9.



Обратите внимание на строку метода document.write. Здесь в кавычках указано то, что нужно непосредственно поместить на страницу. Переменные же указаны вне кавычек, чтобы в документ записывались их значения. Вся строка соединяется знаками “+”.

Чтобы получить результат умножения переменной i на переменную j, использована запись “i*j”. Знак * означает в JavaScript умножение, а знак / (косая черта) — деление. Есть еще операция “остаток от деления”, обозначаемая знаком %. Значение произведения i*j в нашем примере заключено в скобки, чтобы исключить возможность неправильной интерпретации броузером, хотя это не обязательно.

В принципе, наша таблица уже готова! Осталось только объявить переменные i и j в начале сценария (вообще-то, как правило, этого можно даже и не делать, но во избежание случайных ошибок лучше перестраховаться, да и вообще объявление переменных является хорошим тоном и облегчает восприятие кода). Для этого надо использовать ключевое слово var:

var i,j;

Кроме того, для улучшения восприятия, можно “разлиновать” таблицу, отделив столбцы друг от друга. Для этого, как вы помните, нужно исполь зовать атрибут RULES= тега

<TABLE>:

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

Последним штрихом к форматированию нашей таблицы будет выравнивание текста в ячейках по правому краю. Для этого можно просто добавить после тега

<TABLE>

тег

<COLGROUP SPAN=10 ALIGN-"right">

или же просто определить в стилевом блоке свойство для тега

<TD>:

TD { text-align: right; )

В нашем случае этот вариант, пожалуй, предпочтительнее, поскольку некоторые броузеры могут не распознать атрибут ALIGN= тега

<COLGROUP>.

Теперь давайте посмотрим, что у нас получается в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Ta6лица умножения</TITLE>

</HEAD>

Teг <COLGROUP> задает группировку столбцов таблицы, а тег <COL> — вид каждого столбца, принятый по умолчанию.


К сожалению, не все броузеры интерпретируют эти теги достаточно корректно.

<STYLE> BODY { text-align: center; background-color: #FCF7EC;

} TD { text-align: right; } </STYLE>

<BODY>

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

<TABLE BORDER""!" CELLSPACING="0" CELLPADDING="2" RULES="cols">

<SCRIPT> <!-- var i, j ; for (i=2; i<=10; i++) { document.write ("<TR>"); for (j=2; j<10; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>") ; document.write ("</TR>") ; }

//-->

</SCRIPT>

</TABLE>

</BODY>

</HTML>

Результат работы этого кода показан на рис. 6.4. Кстати, вы можете заметить, что выравнивание по правому краю в каждой ячейке таблицы все же не совсем эстетично. Лучше было бы, если бы все знаки равенства в одном столбце находились один под другим. Вообще говоря, для этого в HTML 4.0 есть способ, называемый выравниванием по символу.

<COLGROUP SPAN=10 ALIGN="char" CHAR="=">

По идее, такая запись должна дать как раз требуемый результат — выровнять все знаки равенства в каждом столбце. Однако на момент написания этих строк такая возможность еще не реализована ни в одном броузере!


Указание языка сценариев


Прежде чем пойти далее, давайте рассмотрим еще вот какой вопрос. Дело в том, что тег

<SCRIPT>

, так же как и другие теги, может иметь свои атри буты. Это LANGUAGE= (язык) и TYPE= (тип). В первом указывается язык, на котором написан сценарий. По умолчанию, значением этого атрибута явля ется JavaScript, так что если вы пишете обычный JavaScript-сценарий, то можете спокойно не указывать этот атрибут. Однако, если вы используете особенности версий 1.1 или 1.2 этого языка, то это необходимо указать:

<SCRIPT LANGUAGE”"JavaScript1.1">

ИЛИ

<SCRIPT LANGUAGE""JavaScript1.2">

Правда, распознать это смогут только броузеры Netscape последних версий. А если вы пишете страницу для отображения в броузере Internet Explorer, то можете использовать вообще другой язык — VBScript. Для этого необходимо указать соответствующее значение атрибута LANGUAGE=:

<SCRIPT LANGUAGE="VBS">

ИЛИ

<SCRIPT LANGUAGE="VBScript">

что, вообще говоря, одно и то же. В отдельных случаях могут применяться другие языки, для чего определены такие значения атрибута LANGUAGE=, как LiveScript, tal, PHP и другие.

Что касается атрибута TYPE=, то в нем можно на всякий случай указать тип сценария. В большинстве случаев это text/javascript (или text/vbscript для сценариев, написанных на VBScript).



Управление амплитудой


Кроме того, фонограмма может иметь слишком малую амплитуду. Как .правило, с меньшими потерями сжимаются фонограммы, максимальная амплитуда которых достигает приблизительно -1 дБ. Если фонограмма слишком тиха, увеличьте ее уровень, а если он достигает 0 дБ, то лучше ero немного уменьшить. Для этого лучше всего пользоваться функцией нормализации. Например, в программе Sound Forge выберите из меню Process (Обработка) пункт Normalize (Нормализация). Установите уровень на отметку -1 дБ. Программа сама определит максимальный уровень амплитуды в записи и пересчитает в соответствии с ним все остальные уровни. Только обратите внимание, что при нормализации следует производить увеличение уровня до -1 дБ пиковой амплитуды — в Sound Forge это переключатель Peak. Если включить переключатель RMS, то все операции будут производиться со средним значением амплитуды сигнала, что для данного случая не подходит.

Но это еще не все. Описанная выше операция помогает, если уровень сигнала в записи остается практически постоянным. Однако бывают случаи, когда при наличии нескольких пиков на уровне около 0 дБ уровень всей остальной записи не поднимается, например, выше -30 дБ. В этом случае для получения лучшего звучания при сжатии необходимо уменьшить динамический диапазон записи. Для этого в Sound Forge существует функция Dynamics (Динамический диапазон). В других программах она может называться как-нибудь вроде Compressor/Expander/Limiter. В программе Sound Forge из меню Effects (Эффекты) выберите пункт Dynamics (Динамический диапазон) и далее — Graphic (Графическое представление). В открывшемся окне в большинстве случаев можно просто выбрать один из предварительно заданных наборов настроек. Нажав на кнопку Preview (Предварительное прослушивание), можно проверить результат.

Обратите также внимание на ползунковые регуляторы Threshold (Порог) и Ratio (Степень). Первый определяет порог уровня сигнала, ниже которого начинает действовать компенсация — соответствующее усиление сигнала. Регулятор Ratio определяет степень этой компенсации.



Управление “подсветкой” кнопок


Теперь назначим обработчику событий onMouseOver смену изображения. Собственно говоря, для этого нужно всего лишь изменить атрибут SRC= тегa

<IMG>:

<IMG SRC="'Images/altavista.jpg" WIDTH="192" HEIGHT="40" BORDER="0" ALT="Altavista" onMouseOver="this.src='Images/altavista2.jpg'">

Теперь при наведении указателя мыши на кнопку Altavista вид кнопки изме нится, так как будет загружен другой рисунок. Точно таким же способом Iнужно сменить изображение обратно при выведении указателя мыши за пределы кнопки:

<IMG SRC="Images/altavista.jpg" WIDTH="192" HEIGHT="40" BORDER=0" ALT="Altavista" onMouseOver="this.src='Images/altavista2.jpg'" onMouseOut="this.src='Images/altavista.jpg'">

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

.

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

Можно, конечно, написать такую же конструкцию и для остальных трех кнопок. Однако, давайте реализуем более изящное решение: напишем одну функцию, которая будет менять файл рисунка для всех тегов <IMG>, имеющихся на странице. Точнее, функций будет две: одна для событии onMouseOver, а другая — для onMouseOut. Воспользуемся тем, что файлы рисунков “подсвеченных” кнопок имеют те же имена, что и файлы рисунков обычных кнопок, плюс цифра 2 (например: altavista.jpg — altavista2.jpg). Пусть первая функция, реагирующая на наведение мыши, просто встав ляет двойку в нужное место:

function changel() { if (window.event.srcElement.tagName="IMG")

window.event.srcElement.src= window.event.srcElement.src.substring(0, window.event.srcElement.src.length4)+"2"+ window.event.srcElement.src.substring (window.event.srcElement.src.length-4, window.event.srcElement.src.length) ;


}

Как видите, эта функция сначала проверяет, на какой объект, собственно, наведен указатель мыши, и если это элемент

<IMG>

, то в нужное место значения его атрибута SRC= вставляется цифра 2, а если это какой-нибудь другой элемент, то функция просто ничего не делает. Вроде все правильно, однако слишком громоздко — так сразу и не разберешься, что эта функция делает, да и при вводе таких строк легко ошибиться и потом долго и мучительно искать, почему выдаются сообщения об ошибках. Сократим этот год, присвоив значение window.event.srcElement временной переменной:

function changel() { var a=window.event.srcElement; if (a.tagName=="IMG")

a.src=a.src.substring(0, a.src.length-4)+"2"+ a.src.substring(a.src.length-4, a.src.length);

}

Вот это совсем другое дело — смотрится гораздо прозрачнее, а функционирует точно так же.

Теперь напишем аналогичную функцию, удаляющую двойку из значения атрибута

SRC=function change2() { var a=window.event.srcElement; if (a.tagName="IMG")

a.src=a.src.substring(0, a.src.length-5)+ a.src.substring(a.src.length-4, a.src.length);

}

Вам осталось только назначить обработчики событий. Поскольку мы не нем, для каких конкретно элементов их назначать и сколько, назначим объекту document (обратите внимание, что внутри функций не зря про наводится проверка на имя тега):

document.onmouseover=changel ;

document.onmouseout=change2;

последние две строки также должны находиться в блоке

<SCRIPT>

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


Управление расположением элементов веб-страницы с помощью таблиц


В World Wide Web довольно часто встречаются страницы, на которых произвольное расположение элементов достигается с помощью таблиц. В частности, такой подход часто применяют, если необходимо оставить на странице относительно большие “пустоты”.

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

Сначала определим стили будущей страницы — цвет фона и центрирование текста:

<STYLE> BODY { background-color: #FOE7F1;

} H2 { text-align: center;

} TD { font-family: MS Comic Sans, sans-serif;

text-align: center; } </STYLE>

Теперь можно задать параметры самой таблицы. При этом отступ от внутраннего края ячейки (CELLPADDING=) и расстояние между ячейками (CELLSPACING=) лучше задать равными нулю, чтобы ничто не отвлекало нас от задания минимальных размеров ячеек:

<TABLE WIDTH="99%" CELLSPACING="0" CELLPADDING="0">



Управление шириной столбцов


Если вы посмотрите на рис. 2.2

0

, то увидите, что ширина столбцов в нашей таблице разная. Это происходит потому, что броузер распределяет место в таблице в зависимости от количества текста, которого в первом столбце оказалось больше. Однако, если в теге первой ячейки указать

<TD WIDTH="50%">

,

то оба столбца станут равными по ширине. Таким образом, можно пользоваться атрибутом

WIDTH=

в теге

<TD>

так же, как и в теге

<TABLE>

,

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

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

WIDTH=.

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



Управление шрифтом


Чтобы изменить размер шрифта, можно использовать тег

<FONT>

с атрибутом SIZE=. Вообще говоря, WWW-консорциум не особенно рекомендует использовать тег

<FONT>

в HTML 4.0. Мы считаем, что злоупотреблять им действительно не нужно, когда есть возможность использования каскадных таблиц стилей CSS, о чем мы поговорим в главе 4. Однако иногда для мелких корректив этот тег бывает очень удобен. Например, если мы поставим перед вступительным текстом тег

<FONT SIZE="+1">

f поcле него — закрывающий тег </FONT>, то весь текст, оказавшийся между этими тегами, будет отображен шрифтом на один “уровень” круп-нее обычного.

Возникает вопрос: а каков размер “обычного” шрифта? В языке HTML для тега

<FONT>

были определены семь основных размеров шрифта, измеряемых не в пунктах, а в некоторых условных единицах — от 1 до 7. Как правило, обычный шрифт имеет размер “З”, если не определено иное с помощью тега

<BASEFONT>

(например, так:

<BASEFONT SIZE="6">)

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

Необходимо различать записи

<FONT SIZE="+1" и <FONT SIZE="1">

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

<FONT SIZE="-1">

. Можно использо- вать также значения "+2", "-2", "+3" и т. д. Кстати, для увеличения или уменьшения шрифта на одну единицу можно использовать также теги

<BIG>

и

<SMALL>

(они используются с закрывающими тегами).

Теперь давайте выделим еще некоторые элементы нашей страницы. Чтобы отобразить подзаголовки рассказов курсивом, их можно поместить между тегами

<I>

и

</I>

:

<Н2><Р АLIGN+"center">ИВАН-ЦАРЕВИЧ И СЕРЫЙ ЗАЯЦ<ВК> <I>сказка</I></Р></Н2>


Такой же результат, как тег

<I>

, дает тег

<ЕМ>

. Отличие их в том, что тег

<ЕМ>

определяет лишь логически выделенный фрагмент, который броузеры обычно отображают курсивом, а тег

<I>

— это явное указание на кур сив. Впрочем, это уже несущественные детали.

Мы можем также выделить фамилию нашего героя во вступительном тексте полужирным шрифтом, используя тег

<В>

:

<В>Сергей Сергеев</В> - писатель-авангардист, автор 20 рассказов.

Такой же результат даст использование тега

<STRONG>

. Более гибко управлять выделением можно с помощью CSS

Для выделения какой-либо части текста можно использовать подчеркивание, поместив текст между тегами

<U>

и

</U>

. Однако злоупотреблять этим не следует, поскольку подчеркнутый текст в WWW ассоциируется с гиперссылками и читатель будет весьма разочарован, когда щелчок мыши по подчеркнутому тексту ни к чему не приведет.

Иногда требуется также зачеркнуть отдельные слова в тексте (например, при снижении цен на товары обычно указывают старую цену в зачеркнутом виде). Для этого служит тег

<STRIKE>:

Старая цена: <STRIKE>168 рублей </STRIKE> Новая цена: <FONT SIZE="+1">102 рубля</FONТ>

Результат представлен на рис. 2.3. Некоторые броузеры понимают также сокращенное написание этого тега —

<S>

. Однако для хорошей совмести мости пользуйтесь лучше тегом

<STRIKE>

(пока возможно, совместимость

со всеми броузерами все же лучше поддерживать, тем более что на данном этапе это совсем несложно).



Рис. 2.3. Применение зачеркнутого текста

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


Управление выравниванием текста


В данном случае нам потребуется такой атрибут, как выравнивание (выключка) текста. Он может употребляться с разными тегами. Поскольку на нашей страничке и заголовок, и эпиграф должны быть отделены друг от друга и от основного текста, имеет смысл употребить тег

<Р>

. Каждый фрагмент текста, заключенный между тегами

<Р>

и

</Р>

, будет представлять собой отдельный абзац:

<Р>Это первый абзац.</Р> <Р>Это второй абзац.</Р> <Р>Это третий абзац и т. д.</Р>

Чтобы выровнять заголовок по центру страницы, можно написать следующее:

<Р ALIGN="center">3AГOЛOBOK РАССКАЗА № !</Р>

Вы, очевидно, уже поняли, что атрибут ALIGN= означает выравнивание. Ему присвоено значение "center" для выравнивания текста по центру страницы. Между атрибутом и его значением всегда должен стоять знак равенства. Для того чтобы расположить эпиграф по правому краю, надо, соответственно, атрибуту ALIGN= присвоить значение "right":

<Р ALIGN="right">ЭПИГРАФ</P>

Теперь давайте посмотрим, как будет выглядеть вся страничка целиком.

<HTML>

<HEAD>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">

<TITLE>Домашняя страница Сергея Cepreeвa</TITLE>

</HEAD>

<BODY>

 

<FONT FACE="Times New Roman"><P>Домашняя страница Сергея Сергеева<BR>

<BR>

Сергей Сергеев - писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<BR>

<BR>

Некоторые его рассказы вы можете прочитать прямо здесь. </P>

<P ALIGN="CENTER">ИBAH-ЦAPEBИЧ И СЕРЫЙ ЗАЯЦ<BR>

сказка</Р></P>

<P ALIGN="RIGHT">Hy, погоди!.. <BR>

(Из мультфильма)</P>

<P>Жил да был Иван-Царевич, и все у него было: и злато-серебро, и невест полный дворец, и книжек много умных, и тренажерный зал огромный.
Однако тоскливо было у него на душе - как встанет утром с постели царской, так и начнет горевать, и горюет до вечера.<BR>

Долго ли, коротко ли, ... ( тут располагается еще несколько абзацев, разделенных тегом BR, хотя это не единственный способ разделения абзацев)...<BR>

И они жили долго и счастливо и умерли в один день. </P>

<P ALIGN="CENTER">MOЛOTOK<BR>

рассказ</P>

<P ALIGN="RIGHT">Мы кузнецы, и дух наш молод.<BR>

(Из песни)</P>

<P>Это случилось очень давно, уж и не помню в каком году, в каком веке и в каком тысячелетии... (Здесь располагается текст рассказа) </P></FONT>

</BODY>

</HTML>

Результат показан на рис. 2.1. Как видите, это весьма похоже на то, что было задумано. Однако сразу бросаются в глаза несколько недостатков. Во-первых, абзацы в основном тексте на вид плохо отделены друг от друга, хотя и разделены тегом

<BR>

.



Рис. 2.1. Иллюстрация применения атрибута ALIGN


Усложненный пример


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

function callitO { var q; q=prompt ("Введите целое число от 0 до 170", "5") ;

q=parselnt(q) ; if (isNaN(q)) alert ("Должно быть введено ЧИСЛО в пределах от 0 до 170");

else if ((q<0)|| (q>l70)) alert ("Чиг-ло должно быть в пределах от 0 до 170");

else document .write<q+"! = "+fct(q)+"<BR>");

}

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

Теперь мы можем вызывать ее из “тела” документа сколько угодно раз, написав просто callit(). Например, можно организовать цикл для 10-кратного ее вызова:

for (var j=1; j<11; j++) callit();

Можно также организовать бесконечный цикл:

while (true) callit();

Для этого мы использовали оператор условной организации цикла while. Он проверяет условие, которое записано в скобках, и, если оно верно, выполняется действие (или блок действий), указанное после этого оператора.

Так повторяется до тех пор, пока условие не станет неверным. Здесь мы в качестве условия поставили ключевое слово true, которое всегда будет воз вращать значение “истина”. Поэтому цикл получится бесконечным.

Однако хорошо бы сначала спросить мнение пользователя, желает ли он повторения цикла, а то мы так и не позволим ему уйти со своей страницы. Для этого можно воспользоваться методом confirm. Он очень похож на метод alert, однако здесь пользователь имеет возможность нажать одну из двух кнопок (ОК или Отмена). Если нажата кнопка ОК, возвращается значение “истина” (true), если нажата кнопка Отмена, возвращается значение “ложь” (false).


while (confirm ("Повторить?")) callit();

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

do callit(); while (confirm ("Повторить?"));

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

Вот как будет вьглядеть текст этой веб-страницы целиком.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Вычисление факториала</ТITLЕ>

<SCRIPT> function fct(a) { if ((a=0)| | (a=l)) return 1;

else { var i=l ; for (a; a>l; a--) i*=a; return i; } }

function callit() { var q; q=prompt ("Введите целое число от 0 до 170", "5") ; q=parselnt(q) ; if (isNaN(q)) alert("Должно быть введено ЧИСЛО в пределах от 0 до 170");

else if ( (q<0) | | (q>170) ) alert("Число должно быть в пределах от 0 до 170");

else document.write(q+"! = "+fct(q)+"<BR>");

} </SCRIPT>

</HEAD>

<BODY>

<SCRIPT> do callit() ;

while (confirm ("Повторить?")) ;

document.write("<HR WIDTH=100 ALIGN”'left'>");

</SCRIPT>

</BODY>

</HTML>

Действие этого кода показано на рис. 6.5. Как видите, результат каждого вычисления помещается в окно броузера. Если сейчас нажать кнопку Отмена, под результатами будет проведена горизонтальная черта.



Рис. 6.5. Расчет факториалов и запрос к пользователю

Конечно, появление лишних диалоговых окон в некоторых случаях может отпугнуть пользователя, особенно если у него на полную громкость вклю чены звуковые колонки (вывод окон alert и confirm обычно сопровождается стандартными звуками Windows). Поэтому лучше бы воздерживаться от их применения. Вместо этого можно использовать динамическое измене ния содержимого страницы.


Устранение постоянной составляющей


Первое, что может “мешать” сжатию (да и не только сжатию, а вообще любой цифровой обработке звука), — это так называемая постоянная составляющая сигнала. На рис. 5.6 вы можете видеть в левой части вол новую форму обычного синусоидального сигнала (чистого тона), записанного “правильно”, а в правой части — тот же звук с примесью постоянной составляющей. Кстати, на слух эти два звука различить нельзя

2

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

Мы здесь не будем вдаваться в подробности того, как постоянная состав ляющая влияет на цифровую обработку, просто запомните, что ее лучше

Рис. 5.6. Обычный синусоидальный сигнал

и он же с постоянной составляющей удалить. Во многих программах звуковой обработки имеются соответствующие средства. Например, в программе Sound Forge можно выбрать из меню Process (Обработка) пункт DC offset (Постоянное смещение) и в открывшемся окне выбрать автоматическое удаление постоянной составляющей. Программа сама определит ее наличие и, в случае необходимости, удалит.



Устранение выделяющейся спектральной полосы


И, наконец, еще один момент. Если в записи присутствует сильно выделяющаяся спектральная полоса (это можно заметить визуально на так

Рис. 5.7. Две спектрограммы: обычной, звукозаписи и звукозаписи с сильно- выделяющейся частотной полосой

называемой спектрограмме или сонограмме). На рис. 5.7 показаны две спектрограммы звука — для обычной записи и для записи с сильной спек тральной полосой. Если такая выделяющаяся полоса присутствует, то лучше ее перед сжатием “сравнять” с остальными. Обычно это удается сделать с помощью графического эквалайзера. В программе Sound Forge выберите из меню Process (Обработка) пункт EQ (Эквалайзер) и далее — Graphic (Графический). Открывшееся окно очень похоже по виду на обычный графический эквалайзер, с помощью которого останется только уменьшить уровень выделяющейся частотной полосы.

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



Веб-редактор Arachnophilia


Завершив краткий обзор возможностей программы TextPad, давайте рассмотрим другую программу для написания .HTML-кода — Arachnophilia, которую можно получить по адресу www.arachnoid.com/arachnophilia.

Как и в предыдущем случае, программа автоматически подсвечивает синим цветом теги и атрибуты, а значения атрибутов — зеленым, что улучшает зрительное восприятие, хотя проверка правильности тегов и отсутствует. Зато если случайно забыть закрыть тег, то все последующее содержимое файла подсветится бордовым цветом, так что ошибка сразу бросится в глаза. В программе Arachnophilia предусмотрена автоматизация ввода тегов

HTML.

В нижней части окна имеются кнопки, каждая из которых открывает соответствующую кнопочную панель. На этих панелях расположены кнопки для быстрого ввода тегов. Например, если нажать кнопку Styles (Стили), то откроется панель управления, содержащая кнопки для ввода тегов форматирования текста

.

Нажатие на любую из них вводит тег или блок-заготовку. Например, после нажатия на кнопку BR в тексте появится тег <BR>, а после нажатия на кнопку HR — появится сразу целая заготовка:

<HR WIDTH="95%" ALIGN=CENTER>.

Нажатие некоторых кнопок вызывает появление диалоговых окон. Например, нажав на кнопку Color (Цвет), можно открыть стандартное диалоговое окно выбора цвета, а с помощью кнопки TableWiz (Мастер таблиц) открывают диалоговое окно Table Wizard (Мастер таблиц), средствами которого можно предварительно задать количество строк и столбцов в таблице, а также определить ее ширину, цвет линий и некоторые другие параметры .

Отличительной особенностью программы является возможность легкого просмотра веб-страницы в различных броузерах, для чего в меню Preview (Предварительный просмотр) предусмотрен пункт Identify Browser (Указать Лроузер). Здесь можно назначить до шести различных броузеров, в каждом из которых легко открыть создаваемый

HTML-файл

для просмотра, даже не сохраняя его на диске.

Однако самым замечательным свойством программы, пожалуй, является функция Instant View (Немедленный просмотр), которая доступна в меню Preview (Предварительный просмотр).
Если она включена и внутренний броузер, который также имеется в программе, открыт, то все изменения, вносимые в текст

HTML,

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

В программе Arachnophilia существует множество дополнительных полезных функций. Например, в меню Selection (Фрагмент) есть команда Find/Replace/Count (Поиск/Замена/Пересчет), которая позволяет быстро найти или заменить нужные слова в выделенной области, что часто очень выручает при создании веб-страниц. Команда Tag Delimiters (Ограничители тегов) из того же меню позволяет преобразовать угловые скобки, являющиеся общепринятыми ограничителями тегов

HTML, в

специальные символы &lt и &gt, что необходимо, когда надо показать код

HTML

на самой веб-странице. Можно также осуществить обратное преобразование. В этом же меню есть команда Strip all HTML tags (Скрыть теги HTML), с помощью которой можно быстро освободить текст от

HTML-тегов,

например, для переноса его в другую программу. Программа Arachnophilia, кстати говоря, способна читать и записывать файлы формата

RTF(Rich TextFormat).

При открытии RTF-файла предлагается конвертировать его в формат

HTML,

но его можно редактировать и в обычном виде.

Интересно, что программу Arachnophilia 4.0 можно загрузить как в полном виде (это установочный файл размером полтора мегабайта), так и в сокращенном (1 Мбайт), если в системе установлены необходимые библиотеки. Можно также загрузить только исполняемый файл, а остальное дозагру-жать по мере необходимости.


Веб-редактор TextPad


Итак, начнем. Тем, кто предпочитает набирать код

HTML

вручную, но кому не хватает функциональности Блокнота и подобных ему программ, можно посоветовать программу под названием TextPad, которую можно загрузить, обратившись по адресу www.textpad.com. Эта программа по сути весьма похожа на Блокнот, однако разработчики специально предусмотрели некоторые удобства для того, чтобы писать код

HTML

(а также языков Java, С, C++, Perl и еще некоторых). Это выражается в том, что при написании

HTML

-документа все теги автоматически подсвечиваются синим цветом, их атрибуты — темно-синим, а значения атрибутов — зеленым (цвета можно настроить по собственному желанию, так же, как и шрифт). Это очень удобно. К примеру, если автор случайно ошибется в имени тега или атрибута, то оно останется черным, и он сразу поймет, что здесь что-то не то. Правда, проверка не является “ интеллектуальной”: программа может спокойно “разрешить” приписать тегу какое-либо свойство, которого у него в принципе быть не может (спокойно подсвечивает абракадабру типа

<BR ALIGN="top">

или

</BR>

).

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

Веб-редактор TextPad позволяет автоматизировать набор многих тегов. Если не хочется набирать их вручную (многие этого не любят просто из-за того, что приходится переключаться на латинский шрифт), то обратите внимание на левую нижнюю часть окна программы. Там приведен список наиболее распространенных

HTML-тегов,

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

<BR>

, нужно выбрать из списка пункт Block > Break Line. Однако к этому быстро привыкаешь. Почти все пункты списка вставляют теги вместе с закрывающим парным тегом. Например, если выбрать пункт Block

>


Preformatted, в текст автоматически будут добавлены теги и

<PRE>

и

</PRE>

. Некоторые пункты добавляют сразу целые блоки-заготовки. Если, к примеру, выбрать пункт Table (Таблица), в текст будет вставлен такой код:

<TABLE ALIGN="left" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">

<TR ALIGN="left" VALIGN="middle">

<TH></TH>

<TH>?</TH>

<TR ALIGN="left" VALIGN=middle">

<TD> ? </TD>

<TD> ? </TD>

</TABLE>

Значения этих тегов и их атрибутов мы рассмотрим позже, а пока обратим внимание на то, что кроме списка тегов TextPad предоставляет нам также возможность выбирать из списка специальные символы (список HTML Characters), а также, если потребуется, любой управляющий символ, например символы псевдографики

DOS

и другие. Те, кто часто вводят какие-либо последовательности символов, что при написании веб-страниц не редкость, могут облегчить свою задачу, записав в TextPad соответствующие макросы. Для записи макроса надо нажать комбинацию клавиш CTRL+SHIFT+R (или выбрать из меню Macros пункт Record). При этом начнется запись макроса, то есть все последующие действия будут запомнены. Чтобы закончить запись, надо снова нажать комбинацию клавиш CTRL+SHIFT+R, после чего присвоить имя файлу макроса, а также дать название для представления макроса в меню. Здесь можно также дать, если нужно, краткое описание макроса и указать имя его автора. После нажатия на кнопку ОК название макроса появится в меню Macros. Выбрав его, можно ввести сразу всю заданную последовательность символов.

Для удобства отладки можно установить флажок в пункте Line Numbers (Нумерация строк) в меню View (Вид), — в этом случае все строки текста будут пронумерованы. Хочется отметить, что если в меню Configure (Настройка) включен пункт Word Wrap (Перенос по словам) для автоматического переноса концов длинных строк в видимую часть экрана, то каждая такая длинная строка все равно будет нумероваться одним номером, а не двумя или тремя (кстати, такая нумерация почему-то недоступна в замечательной программе Homesite, о которой речь пойдет ниже).


А если в меню View (Вид) включить флажок Visible Spaces (Отображать пробелы), то можно увидеть на экране и “невидимые символы”, такие, как пробелы, символы табуляции и прочие.

В программе TextPad можно легко сравнить два файла, выбрав из меню Tools (Сервис) пункт Compare Files (Сравнить файлы). А если есть два (или более) похожих файла, в некоторые местах которых надо внести изменения, удобно использовать функцию Synchronize Scrolling (Одновременная прокрутка) из меню Configure (Настройка). В этом случае можно открыть сразу несколько файлов, например, выбрав из меню Windows (Окна) пункт Tile Vertically (Расположить по вертикали), и тогда при прокрутке одного из них другие прокручиваются синхронно. Среди других полезных функций программы TextPad стоит отметить возможность автоматической смены клавиатурного регистра командой Edit

>

Change Case (Правка

>

Сменить регистр), автоматического копирования в буфер слова или строки, на которой находится курсор, с помощью команд Edit ” Cut Other (Правка

>

Вырезать) и Edit

>

Сору Other (Правка

>

Копировать), а также функцию проверки орфографии Tools

>

Spelling (Сервис

>

Правописание). И, конечно, здесь присутствует возможность просмотра созданного файла в броузере View

>

In Web Browser (Вид

>

В броузере).


Веб-редакторы типа WYSIWYG


Мы рассмотрели программы, в которых основной упор при создании веб-страниц сделан на написание

HTML-коца.

вручную. Однако существуют программы, позволяющие редактировать веб-страницы как бы в режиме WYSIWYG.

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

Эффективно управлять оформлением страницы таким способом тоже не удается. Поэтому мы не будем долго задерживаться на веб-редакторах, работающих по прнципу

WYSIWYG.

Вообще говоря, для редактирования HTML-текста в режиме

WYSIWYG

можно использовать даже такой текстовый процессор, как Microsoft Word. Начиная с версии MS Word 97 он позволяет набрать некоторый текст, отформатировать его и сохранить в формате

HTML.

Если будете это делать, не забудьте удалить комментарии...



Вложенные наборы фреймов


— Хорошо, — скажете вы, а как быть, если мы захотим, к примеру, oто- бразить заголовок страницы во всю ширину окна броузера, а уж под ним расположить левый и правый фреймы?

— Это весьма просто. Создадим отдельный НТМL-файл заголовка.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<ТITLЕ>Домашняя страница Сергея Сергеева. </TITLE>

<STYLE TYPE="text/css">

<!--

BODY { background-color: #BABAAO;

color: rgb(29,29,24); . } HI { text-align: center; }

-->

</STYLE> </HEAD>

<BODY>

<Н1>Домашняя страница Сергея Сергеева</Н1>

</BODY>

</HTML>

Назовем этот файл, например, serghdr. html. Далее удалим заголовок из файла sergtext.html. И теперь давайте немного подумаем. Чтобы расположить наш заголовок в верхнем фрейме, придется сначала определить набор горизонтальных фреймов с помощью атрибута ROWS= в теге

<FRAMESET>:

<FRAMESET ROWS="80,*" FRAMESPACING="0" FRAMEBORDER="0">

Здесь мы определили высоту верхнего фрейма в 80 пикселов — вполне достаточно для заголовка. Теперь определим содержимое верхнего фрейма (загрузим туда наш только что созданный файл serghdr.html):

<FRAME SRC="serghdr.html" NAME="header" FRAMEBORDER="0" SCROLLING="no">

Теперь нужно определить содержимое нижнего фрейма. А что там должно находиться? А там должен находиться тот самый набор фреймов, который был определен в прошлом примере! К счастью, нам ничто не мешает в качестве содержимого одного из фреймов указывать тег

<FRAMESET>

— ведь каждый фрейм имеет те же “права”, что и отдельное окно броузера! Вот что у нас получится в целом.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">

<HTML>

<HEAD>

<ТITLE>Домашняя страница Сергея CepreeBa</TITLE>

</HEAD>

<FRAMESET ROWS="80,*" FRAMES РАСING="0" FRAMEBORDER="0">

<FRAME SRC="serghdr.html" NAME="header" SCROLLING="no">

<FRAMESET COLS="277,*" FRAMESPACING="0" FRAMEBORDER="0">

<FRAME NAME="portrait" SRC="sergport.html" SCROLLING="no" NORESIZE>

<FRAME NAME="text" SRC="sergtext2.html" SCROLLING="auto" NORESIZE>

</FRAMESET> </FRAMESET> </HTML>



Внешние гиперссылки


Однако гиперссылки можно устанавливать не только на файлы, содержа-щиеся в своем каталоге на сервере, но и на любые другие Интернет-ресурсы. В этом случае в качестве значения атрибута HREF= необходимо указать полный URL-appec ресурса, как показано ниже. Рассмотрим такой пример. Допустим, мы хотим сделать страничку, с которой можно легко попадать на излюбленные поисковые системы

1

. Естественно, для этого необходимо указывать полные URL-адреса этих сайтов, например, вот так:

Поисковая машина

<А HREF="http://www.altavista.com">"Altavista" </А>

Теперь предположим, что мы хотим оставить пользователю возможность велнуться после посещения поисковой машины на нашу страничку. Но как это сделать? Ведь на поисковых машинах, скорее всего, гиперссылок на нее нет.

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

<А>

установить атрибут TARGET= со значением "_blank", следующим образом:

Поисковая машина

<А HREF="http://www.altavista.corn" TARGET="_blank">"Altavista"</A><BR>

Давайте теперь вспомним, как задавать на страничке цвета и элементы форматирования текста, и посмотрим, что может получиться в целом.

<html>

<head>

<title>Поисковая машина</title>

</head>

<body BGCOLOR="#FPAEAE" TEXT="#480000" LINK="#C10000"

VLINK="#C10000" ALINK="#C10000">

<H1><DIV ALIGN="center">Поисковая машина</DIV></H1>

<br>

Если вы ищете в Интернете какую-либо информацию, вам помогут

следующие сайты:

<br><br>

Поисковая машина <A HREF="http://www.altavista.corn"

TARGET="_blank">"Altavista"</A><br>

Каталог ресурсов <A HREF="http://www.yahoo.corn"


TARGET="_blank">"Yahoo! "</A><br>

Поисковая машина <A HREF="http://www.yandex.ru"

TARGET="_blank">"Яndex"</A><br>

Поисковая машина <A HREF="http://www.aport.ru"

TARGET="_blank">"Anopт"</a>

</BODY>

</HTML>

Результат показан на рис. 2.8. Как видите, ничто не указывает на тот факт, что сайты поисковых систем будут загружаться в новое окно; пользователь увидит это только после щечка на гиперссылке.



Рис. 2.8. Применение гиперссылок для связей с удаленными серверами

Помимо значения "_blank", атрибут TARGET= может принимать еще значения "_self", "_top" и "_parent"; его значением может также быть имя любого окна. Однако все это мы рассмотрим позднее, Пока же запомните только, что значение "_blank" вызывает загрузку странички в новое окно броузера, а значение "_self" — в то же окно, в котором был сделан щелчок на гиперссылке. Собственно говоря, значение "_self определено по умолчанию.

И еще одно: не следует слишком злоупотреблять значением TARGET="_blank", поскольку при множестве открытых окон броузера читатель в них может легко запутаться и у него останется негативное ощущение. А вообще, гиперссылки всегда очень помогают в навигации в Интернете. Их никогда не бывает слишком много.


Внешние стилевые таблицы


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

<STYLE>

и

</STYLE>

) в отдельном файле с расширением .css, а затем “подключить” ее во всех HTML- документах, которые должны ее использовать. Например, если файл таблицы стилей называется mainstyle.css, то в раздел

<HEAD>

каждого из использующих ее HTML-документов, нужно вставить такую строку:

<LINK REL="Stylesheet" HREF="mainstyle.css" TYPE="text/css">

Атрибут TYPE= указывать не обязательно, но лучше это сделать (кстати, это можно делать и в теге

<STYLE>

). Во-первых, это признак хорошего тона, а потом мало ли что — вдруг пользователю, к примеру, попадется какой-нибудь сумасшедший броузер, использующий для стилевых таблиц по умолчанию не CSS, а, допустим, JASS.

Есть и другой способ “подключения” стилевой таблицы из внешнего файла — директива @import. Она употребляется следующим образом:

<STYLE TYPE="text/css"> @import url (mainstyle.css) ; </STYLE>

Как видите, эта директива должна находится между тегами

<STYLE>

и

</STYLE>

, поскольку она не является элементом языка HTML (как тег

<LINK>

). Ее использование менее предпочтительно, поскольку броузеры могут интерпретировать ее по-разному.



Встроенные функции JavaScript


Теперь о функциях. Мы уже научились определять собственные функции. Кроме того, в JavaScript существуют так называемые встроенные (или предопределенные) функции. Некоторые из них мы уже знаем — это isNaNQ и parselnt(). Кстати, функция parselnt() имеет еще одну замечательную особенность: с ее помощью можно распознать число, введенное в любой системе счисления, начиная от двоичной и кончая 36-ричной. Для этого нужно просто в качестве второго аргумента указать основание системы счисления, например, вот так: parselnt("1110", 2);

В этом случае строка 1110 будет интерпретирована как двоичное число, и результатом функции будет число 14.

Кроме этих двух функций существуют еще функции parseRoat() и isFinite(). Функция parseFloat() не может принимать второй аргумент, зато может выделить из строки дробное число. Например, если написать

parseint("3.289 times"); то результатом выполнения функции будет число 3, а если написать

parseFloat("3.289 times");

результатом будет число 3,289. Кроме того, с помощью этой функции можно распознать число, введенное в нормализованной форме, например:

parseFloat ("3.755е-2") ; даст в результате 0,03755.

Что касается функции isFinite(), то она принимает значение истина, если аргумент является числом, или ложь — в противном случае. Как вы можете заметить, она делает то же, что и функция isNaN(), только с противоположным результатом.

Существует еще полезная функция eval(). Она обычно определяется, как вычисление выражения без ссылки на конкретный объект. Сходу это понять довольно трудно.

Иногда в JavaScript используются конструкции, очень похожие на функции. Например, в одном из предыдущих разделов для возведения в степень мы написали:

Math.pow(j,i)

Такие конструкции, как правило, являются методами одного из встроенных объектов. Если вы пока плохо представляете себе, что это такое, не огорчайтесь. Для их употребления это совершенно не важно, поскольку их синтаксис очень похож на синтаксис функций. Например, выше было продемонстрировано возведение в степень. Можно осуществлять и другие действия с помощью объекта Math. Например, для округления числа i до ближайшего целого достаточно написать Math.round(i), а для вычисления его синуса — Math.sin(i).

Кроме того, можно пользоваться свойствами объекта Math. Если, к примеру, потребовалось ввести число тг, то не стоит вспоминать его с точностью до какого-то там знака — достаточно написать вместо него Math PI. Можно точно так же определить другие важные математические константы.

Помимо объекта Math, в JavaScript имеются и другие, например Array для работы с массивами, Date для работы с датами и прочие.



Ввод данных пользователем в формы HTML


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

Этот способ заключается в построении так называемых форм. Он состоит в том, что на веб-страницу выводится, к примеру, несколько текстовых полей, куда пользователь может ввести какой-либо текст, а потом с помощью специальной кнопки отправить его серверу. Вместо ввода текста пользователю может быть предложено выбрать несколько пунктов из заготовленного списка или отметить флажками нужные пункты и т. п. Такое взаимодействие с пользователем весьма условно — ведь информация, кото рую он ввел и отправил, все равно обрабатывается на стороне сервера.



Выбор изменяемых свойств


Кстати, использование переменной-флага дает нам возможность легко переделать это мигание во что-нибудь другое. Например, вместо временного исчезновения надписи можно на это время включать выворотку, то есть взаимно поменять цвет текста и цвет фона. Как мы уже говорили, получив доступ к элементу (например, через метод document.all), мы можем легко изменить любое его свойство. Вот, например, как можно организовать мигание с вывороткой:

function blink it() { if (vis"1) { document.all.mig.style.backgroundColor="#OD160E document.all.mig.style.color="#F9FFF9"; vis=0;

} else { document.all.mig.style.backgroundColor="#F9FFF9" ;

document.all.mig.style.color="#OD160E"; vis=l; } setTimeout ("blink_it()", 400); }

Результат (в момент включения выворотки) показан на рис. 6.7. Обратите внимание на то, что стилевые свойства, которые пишутся через дефис в нашем примере это background-color), при доступе из сценария необходимо писать без дефиса, но заменив букву, идущую после дефиса, на прописную. Так, background-color превращается в backgroundColor, font-size в fontSize, border-style в borderStyle и т. д. Кстати говоря, чтобы получить тот результат, который показан на рис. 6.10, нам пришлось добавить еще одно свойство нашему мигающему элементу:

<Н2>Производство <DIV ID="mig" STYLE="text-decoration: blink; width: 7em; visibility: visible;">МИГАЛОК</DIV> и цветомузыкальных установок.</Н2>

а именно: мы установили ширину элемента. Если этого не сделать, цвет фона будет меняться на этой строке по всей ширине экрана.

Рис. 6.7. Мигание заголовка может осуществляться разными способами, в том числе и вывороткой

Доступ к элементам страницы через метод document.all — вещь очень удобная. К сожалению, такая возможность на 100% поддерживается только в броузере Internet Explorer. Что касается броузеров Netscape, то доступ к любому элементу там появился только в шестой версии, но синтаксис его отличается от рассмотренного выше.
Вместо documental).имя_элемента для Netscape 6 нужно писать document.getElementByld("имя_элементa"). А в более ранних версиях Netscape доступ обеспечивается только к некоторым элементам страницы: рисункам (document.images), ссылкам (document.links), якорям (document.anchors), элементам управления и внедренным объектам (document.applets), формам (document.forms), объектам, внедренным с помощью тега

<EMBED>

(document.embeds), а также слоям, которые в Netscape организовывались с помощью тега

<LAYER>

(через document, layers). При этом, правда, все равно можно присваивать этим элементам уникальные имена и затем использовать их для обращений, например, так:

<A NAME="colored">Какой-то текст<А> <SCRIPT> document.anchors.colored.style.color="red"; </SCRIPT>

При этом некоторые версии Netscape позволяют опустить слово style, а при доступе к слоям — и слово layers.

Эти отличия несколько затрудняют создание страниц, которые бы хорошо смотрелись и в Internet Explorer, и в Netscape. Однако всегда можно проверить из сценария тип и версию броузера, после чего написать различные блоки кода для разных броузеров. В некоторых особо сложных случаях можно даже написать отдельные страницы для разных типов броузеров, и организовать перенаправление на них (пример такого перенаправления был приведен в разделе 6.1). В любом случае не забывайте проверять, как веб-страница смотрится в броузерах других типов. Сложно, конечно, поддерживать совместимость со всеми броузерами, но даже если ориентироваться на какой-нибудь один из них, все равно иногда стоит немного подкорректировать код так, чтобы пользователи других броузеров увидели хоть что-то более или менее похожее. Кстати, в этой книге большинство примеров ориентированы на броузер Internet Explorer версии 4 и выше.


Выбор шаблона


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



Выбор способа сохранения


Когда графический элемент создан, его нужно сохранить в оптимальном виде — чтобы качество было получше, а размер поменьше. Для этого в программе Xara WebStyle есть очень наглядная утилита. Если нажать на кнопку Save (Сохранить), открывается диалоговое окно, в котором можно выбрать тип файла —

GIF

или

JPEG

и размер файла (Fast Download — для быстрой загрузки, низкое качество; Medium Quality — среднее качество и средний размер, и High Quality — высокое качество, но и размер побольше). А если нажать на кнопку Advanced (Дополнительно), можно тонко настроить все параметры сохранения файла. Для формата

JPEG

это стандартная шкала качества (от 0 до 100), а для формата

GIF

можно выбрать количество цветов (16 или 256), палитру, режим передачи полутонов, режим чересстрочной развертки и режим прозрачного рисунка. В последнем случае с помощью движка Trim transparency можно выбрать количество цветов, которые будут преобразованы в цвет, назначенный прозрачным. Самое замечательное, что во время всех этих манипуляций их результат можно непосредственно наблюдать в области просмотра, и контролировать при этом размер получающегося файла (указывается в нижней части панели предварительного просмотра). Кроме того, можно нажать на кнопку Browser Preview (Просмотр в броузере) и просмотреть результат работы так, как он будет выглядеть в броузере. При этом выдаются также дополнительные сведения, например время загрузки данного файла при различной производительности модемного соединения с Интернетом.

Обратите внимание на то, что в левом нижнем углу рабочей области практически всегда расположена кнопка Revert (Возврат), позволяющая сделать несколько “откатов” назад, если совершена трудноисправимая ошибка. А в правом нижнем углу часто располагается кнопка Theme (Тема), при нажатии которой предлагаются несколько заранее подобранных вариантов цвета, шрифта и т. п.

Мы рассмотрели работу в программе Xara WebStyle на примере выбора заголовка, но и работа с другими типами графики практически ничем не отличается от рассмотренного примера. Разница заметна лишь в возможностях выбора: например, при создании графического маркера нельзя вводить текст и т. п.

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



Завершая этот краткий обзор приемов



Завершая этот краткий обзор приемов работы с программой Adobe Photoshop, хочется заметить, что за его рамками, разумеется, остались многие возможности программы, например такие, как фильтры, позволяющие размыть изображение, сделать его похожим на барельеф или акварель, добавить шум и т. п. Однако полное описание возможностей этой программы выходит за рамки данной книги. Тем, кто заинтересовался работой в Adobe Photoshop, можно посоветовать обратиться к специальной литературе (см., например, М. Стразницкас. Photoshop 5.5 для подготовки Web-графики. Учебный курс. “Питер”, 2000).

Рис. 3.37 Перемещение выделенной области в одном слое

Замена тегов на стилевое описание


В следующем блоке использован отмененный тег

<FONT>:

<FONT SIZE="+1"><В>Сергей Сергеев</В> - писатель-авангардист, автор 20 рассказов.<BR>

В жизни большой любитель собак и компьютерных игр.<BR><BR>

Некоторые его рассказы вы можете прочитать прямо здесь.<BR>&nbsp;</FONT>

Вы можете спросить, что если атрибут STYLE= легко заменил отмененные атрибуты, то что делать с отмененными тегами? К чему “прикрепить” атри бут STYLE=? В большинстве случаев его можно “прикрепить” к тегу <DIV>. В данном случае мы так и поступим:

<DIV STYLE="font-size: larger;">

Как видите, значения свойства font-size отличаются от значений атрибута SIZE= тега

< FONT>

. Для относительного увеличения размера шрифта исполь зуется значение larger, для относительного уменьшения— smaller. Кроме того, можно, во первых, указывать процентное изменение величины шрифта, например font-size: 120%;, либо его абсолютную величину. Для этого можно использовать либо значения xx-small, x-small, small, medium, large, x-large и xx-large, либо просто указать величину шрифта в пикселах — font-size: 18px; или в других единицах.

Кроме того, в нашем блоке присутствует тег

<В>

, также относящийся к оформлению, хотя почему-то и не отмененный в HTML 4.0. В CSS ему соответствует свойство font-weight: bold;. Однако мы не можем написать вместо

<В>Сергей Сергеев</В> следующее:

<DIV STYLE="font-weight: bold;">Сергей CepreeB</DIV>

поскольку в этом случае следующий текст будет перенесен на новую строку. Поэтому вместо тега

<DIV>

здесь следует использовать тег

<SPAN>

:

<SPAN STYLE="font-weight: bold;">Сергей Сергеев</SPAN>

Этот тег, кстати, бессмысленно применять без атрибутов, поскольку тогда вообще не будет никакого эффекта. Как правило, он применяется именно с атрибутом STYLE= (либо с атрибутами CLASS=, ID=, LANG= или обработчиками событий, о которых речь пойдет ниже).


Свойство font-weight (“жирность” шрифта), кстати, может принимать не только значения bold (полужирный) и normal (обычный), но и любое числовое значение от 100 до 900 (правда, имеют смысл только значения, кратные 100) — то есть, от самого тонкого до самого жирного шрифта. При этом значение 400 — это то же самое, что normal, a 700 — то же, что bold. Можно также употреблять относительные значения bolder и lighter.

Пойдем далее. После этого текстового блока у нас на веб-странице была горизонтальная линия

<HR

>

с отмененным атрибутом W1DTH=, вместо которого следует использовать стилевое свойство width:

<HR STYLE="width: 75%;">

Кроме того, если помните, для организации вертикального отступа между текстом и горизонтальной чертой мы использовали не очень красивую конструкцию

<BR>&nbsp;

. В CSS имеется свойство margin, с помощью кото рого можно регулировать отступы (“поля”) со всех сторон элемента; а для индивидуальной регулировки отступов с каждой стороны можно исполь зовать свойства margin-top (отступ сверху), margin-bottom (отступ снизу), margin- left (отступ слева) и margin-right (отступ справа). Поскольку мы намеревались удалить горизонтальную черту от текста на расстояние, примерно равное одной строке, давайте напишем так:

<HR STYLE="margin-top: 24px; width: 75%;">

Интервал, определенный свойством margin-top, составляет 24 пиксела.

Далее центрируем заголовки рассказов с помощью уже знакомого нам свойства text-align. Но у нас есть еще подзаголовки, выделенные курсивом:

<I>сказка</I>

Поскольку тег

<I>

тоже относится к оформлению (хоть и не отменен), заме ним его стилевым свойством font-style: italic;, применив уже знакомый тег

<SPAN>:

<SPAN STYLE="font-style: italic;">сказка</SPAN>

Кроме значений normal (обычный) и italic (курсив) это свойство может при нимать значение oblique (наклонный шрифт). Различие между наклонным шрифтом и курсивом состоит в том, что буквы курсива имеют иное начер тание.


Правда, при использовании определенных шрифтов большинство броузеров пока что “халтурят” — используют курсив, если нет готового варианта наклонного шрифта.

Стилевое позиционирование

Теперь исправим конструкцию для эпиграфа:

<Р ALIGN="right"XFONT SIZE="-l">Hy, погоди!.. <BR>

<I>(Из мультфильма )</I>

</FONT></P>

Вместо атрибута ALIGN=, а также тегов

<FONT>

и

<I>

применим уже знакомые конструкции:

<Р STYLE="text-align: right; font-size: smaller; ">Hy, погоди!.. <BR><SPAN STYLE="font-style: italic; "> (Из мультфильма) </SPAN></P>

Кстати говоря, на самом деле и эта конструкция, и та, что была в старом варианте, не совсем подходит для эпиграфа. Удачно, что эпиграф у нас короткий. А что бы было, если он был бы немного длиннее, например таким:

<Р STYLE="text-align: right; font-size: smaller;">&laquo;Ну, погоди!..&raquo; &mdash; что есть мочи закричал Волк, стремительно падая вниз с обрывком веревки в лапе прямо на милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.<BR><SPAN STYLE="font-style: italic;">(Из описания мультфильма) </SPAN></P>

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

<BR>

, что привело бы к различным результатам при просмотре в окнах разного размера). А при использовании CSS можно просто использовать такие свойства блока, как width и height (ширина и высота). Второе из них нам сейчас не нужно, а вот свойство width как раз пригодится:

<DIV STYLE="text-align: right;"> <P STYLE="text-align: justify; font-size: smaller; width: 35%;">



&laquo;Hy, погоди!..&raquo; &mdash; что есть мочи закричал Волк, стремительно падая вниз с обрывком веревки в лапе прямо на милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.<BR>

<SPAN STYLE="font-style: italic;">(Из описания мультфильма)</SPAN>

</DIV>

Результат показан на рис. 4.2. Давайте с ним разберемся. Как видно из вышеприведенного кода, просто добавить свойство width: 35%; недоста точно. Действительно, тогда текст блока был бы выровнен по правому краю, но это выравнивание происходило бы внутри блока, а сам блок шириной 35% от полной ширины окна располагался бы слева. Поэтому весь блок, описанный тегом

<Р>

, пришлось заключить во внешний блок

<DIV>

, а уже в нем установить выравнивание по правому краю (text-align:right;). Ну, а раз уж выравнивание по правому краю взял на себя внешний блок, внутри текстового блока для лучшего восприятия мы выровняли текст но обоим краям (text-align: justify;).



Рис. 4.1. Длинный эпиграф при таком, оформлении становится не похожим, на эпиграф



Рис. 4.2. Выравнивание эпиграфа с помощью вложенных блоков

Все бы хорошо, однако подпись под эпиграфом хорошо бы выровнять по правому краю (хотя, поскольку она занимает почти всю строку, это не очень заметно), как на рис. 4.3. Но поскольку тег

<SPAN>

“не понимает” отдельного выравнивания, придется эту подпись также заключить в блок

<DIV>

или <Р>.



Рис. 4.3. Выравнивание подписи под эпиграфом

милицейский мотоцикл, который как раз в этот момент проезжал по дороге. Через мгновение мотоцикл уже увозил его куда-то вдаль.

</Р>

<Р STYLE="text-align: right; font-size: smaller; width: 35%; font-style: italic; position: relative; top:-18px;">

(Из описания мультфильма) </Р> </DIV>

Конечно, последняя конструкция выглядит несколько искусственной — собственно говоря, использованный здесь метод в данном случае напоминает известное выражение “Из пушки по воробьям”.


Зато мы на этом примере сможем познакомиться с позиционированием объектов.

Обратите внимание на свойство position. Оно задает тип позиционирования — относительный или абсолютный. В данном случае определено относительное позиционирование (relative), то есть отсчет ведется от той позиции, которую должен был бы занимать этот элемент, если бы позиционирование не было задано. А абсолютное (absolute) позиционирование означает, что отсчет ведется от верхнего левого угла окна броузера (точнее, его рабочей области). Еще у этого свойства может быть значение static, означающее, что элемент не позиционируется индивидуально, и значение fixed (фиксированная позиция — элемент позиционируется абсолютно и не прокручивается вместе с остальным содержимым страницы), которое, однако, поддерживается пока только шестой версией Netscape.

Со свойством position тесно связаны еще два свойства — top и left, которые задают позицию верхнего левого угла элемента соответственно по верти кали и горизонтали. Чем больше значение top, тем ниже расположен эле мент, и, соответственно, чем больше значение left, тем элемент правее. В данном случае, для того чтобы приподнять текст примерно на высоту одной строки, нам пришлось написать: top: -18px;.

Ну, ладно, мы ведь договаривались пока что не менять ничего на страничке, поэтому вернемся к нашему короткому тексту, однако все равно приме ним к нему вышеуказанную конструкцию (со вложенными блоками <DlV>). Между прочим, даже с коротким текстом это все равно получается краси вее, чем раньше. Только заменим значение width на 130 точек (вместо процентного обозначения), а то при очень большом разрешении экрана короткий текст слишком сильно оторвется от подписи.


Запись формата TwinVQ


Для того чтобы сжать файл в формат TwinVQ, также существует несколько программ. Одной из лучших является YAMAHA Sound VQ Encoder (ее можно загрузить с веб-сайта www.vqf.com). Программа имеет, кстати, довольно оригинальный дизайн. Обращаться с ней крайне удобно. Hа верхней панели можно ввести имя исходного звукового файла или выбрать его, нажав кнопку Browse (Обзор). При этом формат выбранного файла отображается автоматически. Затем с помощью раскрывающегося списке Encode Mode (Режим сжатия) можно задать степень сжатия. Только имейте в виду, что в этой программе указано количество бит в секунду на канал. То есть, если выбрать режим 32 kbps/ch для стереозаписи при установлен ном режиме Стерео, то фактически степень сжатия выходного файла составит 64 Кбит/с (по 32 Кбит/с на каждый из двух каналов).

С помощью переключателя Quality (Качество) можно выбрать качество сжатия: высокое, среднее и низкое. Чем выше качество, тем больше времени требуется программе для сжатия. Однако разница во времени не столь велика, чтобы жертвовать качеством, поэтому практически всегда следует выбирать параметр High (Высокое качество). На нижней панели можно выбрать имя выходного файла (программа по умолчанию предлагает то же имя, как и имя исходного файла, только рас-ширение заменяется на .vqf). Тут же можно указать дополнительные атрибуты, записываемые в ид-файл: название композиции, автора и данные об авторских правах. Можно также ввести собственное примечание.

Если установлен режим Permission to Save (Разрешить сохранение), то пользователь, прослушивающий этот файл в потоковом режиме, сможет сохранить его на жестком диске. Здесь же можно указать имя сохраняемого файла. А если включить режим Low Priority (Низкий приоритет), можно перевести процесс сжатия в фоновый режим. Хотя при этом кодирование займет, разумеется, больше времени, зато можно параллельно заниматься другими делами на компьютере.

С помощью SoundVQ Encoder можно также кодировать сразу несколько файлов в пакетном режиме.
Для этого необходимо просто выбрать файлы в Проводнике Windows и перетащить их значки на панель программы. Далее будут предложены уже знакомые нам варианты настройки.

Кроме того, программа поддерживает функцию сжатия в режиме реального времени (“на лету”). Нажав кнопку Live Encoding (Сжатие в реальном времени), можно сжимать звуковой поток, поступающий на вход звуковой карты. Правда, для такого “живого” сжатия необходима достаточно мощная система.

Чтобы обеспечить потоковое воспроизведение, можно создать так называемый VQL-файл. Это текстовый файл, подобный упоминавшемуся выше RАМ-файлу, однако он может быть многострочным. В каждой строке при этом нужно указать местоположение одного VQF-фаи.ла (в виде полного URL-адреса, включая имя протокола http://). Таким образом, можно создать ссылку на несколько VQF-файлов, следующих подряд, то есть использовать VQL-файл в качестве своеобразного списка воспроизведения. Кроме того, в FQL-файл можно вставлять в конец строки любые примечания, отделив их знаком #.



Существуют и другие программы для сжатия файлов в формат TwinVQ. Некоторые из них можно загрузить, посетив уже упоминавшийся сайт www.vqf.com. Рекомендуем опробовать их самостоятельно.


Запись информации в веб-документ


Для написания динамических веб-страниц используются фрагменты кода, написанные на языке JavaScript (или другом языке сценариев, о чем речь пойдет ниже), который имеет синтаксис, отличный от HTML. Для отде ления этих фрагментов от остальной части HTML-документа они распоагаются между тегами

<SCRIPT>

и

</SCRIPT>

. Например, так:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>SCRIPT!</TITLE>

</HEAD>

<BODY>

<SCRIPT>

document.write("Эта страница написана на JavaScript!");

</SCRIPT>

</BODY>

</HTML>

Результат работы этого кода показан на рис. 6.1. Как видите, пока ничего необычного. Эту же надпись можно было написать и просто так, не используя JavaScript — результат был бы тот же. Зато теперь мы знаем, что если написать метод document.write, то на страницу будет вставлено то, что далее стоит в скобках. Если это текстовая строка, то нужно ее заключить еще и в кавычки.

Рис. 6.1. Простейшее использование JavaScript

Ладно, давайте немного изменим текст кода (для экономии места мы приводим только текст сценария, предполагая, что все остальные теги остаются такими же, как в предыдущем примере):

<SCRIPT> window.status = "Эта страница написана на JavaScript!"; </SCRIPT>

Результат можно увидеть на рис. 6.2. Теперь окно броузера абсолютно пустое! Но это и правильно, ведь мы же не вводили никакого текста. Зато если вы посмотрите на строку состояния, то увидите там нашу надпись. В этой строке всегда появляется значение, присвоенное объекту window.status. Знак равенства в JavaScript означает “присвоить значение”.

Рис. 6.2. Изменение строки состояния

Хорошо, скажете вы, вот мы уже управляем строкой состояния, но где же обещанная динамика? Ну, если не терпится, то можно еще немного изменить код предыдущего примера:

<SCRIPT> window.status = "Эта страница написана на JavaScript!"; setTimeout("window.status = 'А вы как думали?'",2000); </SCRIPT>


Теперь в момент загрузки наша страница будет выглядеть так же, как и в предыдущем примере, однако через две секунды содержимое строки состояния изменится на фразу “А вы как думали?”. Дело в том, что функция setTimeoutO, которую мы здесь использовали, совершает действие, определенное внутри нее, с некоторой задержкой. Эта задержка исчисляется в миллисекундах (тысячных долях секунды). Соответственно, значение 2000 соответствует задержке в 2 секунды.

Само действие определяется в виде строки, то есть должно быть заключено в кавычки. Поэтому фразу “А вы как думали?” пришлось заключить в другой тип кавычек — так называемые одинарные, чтобы броузер не “запутался”. В JavaScript (как и в HTML) допускается использование и тех, и других кавычек, нужно только внимательно следить, чтобы все кавычки в нужном месте закрывались. Нельзя было написать так:

. setTimeout("window.status = "А вы как думали?"", 2000);

поскольку тогда броузер “решил бы”, что строка закончилась после знака равенства, а далее, не встретив запятой, пожаловался бы на ошибку. Кстати, необходимо внимательно следить, чтобы в JavaScript-фрагментах не было ошибок. Вы помните, что если броузер встречает ошибку синтаксиса HTML (например, непонятный ему тег), то он его просто игнорирует. Но если броузер встретит ошибку в коде JavaScript, то будет выдано сообщение об ошибке, причем весь сценарий не будет исполнен.

Еще одна деталь: в JavaScript необходимо соблюдать регистр символов, так как в этом языке различаются прописные и строчные буквы. Напри мер, если вместо setTimeoutO написать SetTimeoutO или settimeoutQ, то будет выдано сообщение об ошибке.


Запись в формате МРЗ


Если желательно получить на выходе файл в формате МРЗ, лучше вос- пользоваться программой МРЗ Producer, которую предлагает компания Fraunhofer. Основное окно этой программы изображено на рис. 5.5. Как видите, здесь все просто и нет ничего лишнего. Нажав кнопку Select Input (Выбор источника), можно выбрать WAVE-файл, подлежащий сжатию. Имя выходного файла предлагается автоматически, но если оно не годится, его можно задать с помощью кнопки Set Output (Задать выходной файл). С помошью раскрывающегося списка можно выбрать степень сжатия и режим (стерео/моно). Интересная особенность этой программы — возможность предварительного прослушивания фрагмента в сжатом виде. Для этого служит кнопка Prelisten (Предварительное прослушивание). С ее помощью можно сравнить между собой различные режимы сжатия и выбрать подводящий. Кодирование начинают щелчком на кнопке Encode (Кодировать).

Рис. 5.5. Основное окно программы Fraunhofer МРЗ Producer Professional

Если в меню Options (Параметры) установлен флажок Write RIFF/WAV- Format Files, то на выходе будет записан файл в формате WAVE. Чтобы получить МРЗ-файл, убедитесь в том, что этот флажок сброшен. А вот флажок High Quality Encoding установите обязательно — тогда качество выходного МРЗ- файла будет гораздо выше при той же степени сжатия. Без этой настройки процесс сжатия происходит гораздо быстрее, но качество при этом хуже — примерно такое же, как в программе AudioCatalyst.

Cписок один или несколько файлов. Щелкнув правой кнопкой мыши на значке любого файла в списке, можно индивидуально изменить степень его сжатия или предварительно прослушать его фрагмент (Prelisten). Нажатие кнопки Encode (Кодировать) запускает процесс сжатия всех файлов. внесенных в список.

Программа МРЗ Producer — очень качественный инструмент для сжатие звука в формат МРЗ. Она имеет лишь два недостатка, о которых, тем не менее, следует знать заранее. Во-первых, при сжатии в режиме моно к выбранном параметре High Quality Encoding она может работать нестабильно и в некоторых случаях “зависать”. Во-вторых, она не поддерживает сте пень сжатия 320 Кбит/с, в отличие от AudioCatalyst. Хотя эта последняя особенность в нашем контексте вряд ли актуальна.



Запись звука от внешнего источника


Итак, если исходный звуковой материал расположен на компакт-диске, то с записью все просто. А что делать, если он расположен на аудиокассете, мини-диске, ЛАГ-кассете или ином внешнем носителе? В этом случае придется осуществить обычную аудиозапись через звуковую карту компьютера. Соедините линейный выход вашего внешнего устройства с линейным входом звуковой карты. Затем дважды щелкните на значке с изображением динамика на панели индикации Windows (рис. 5.1). Откроется окно системного микшера. В нем из меню Параметры выберите пункт Свойства и в открывшемся диалоговом окне выберите пункт Запись. Нажмите кнопку ОК. Появится окно, изображенное на рис. 5.2.

Рис. 5.1. Панель индикации Windows

В этом окне следует выбрать линейный вход (Line). He закрывайте пока это окно — оно нам потребуется для регулировки уровня записи.

Запись звукового материала можно осуществлять даже простой программой, например программой Звукозапись (Пуск > Программы > Стандартные >

Рис. 5.2. Окно системного микшера Windows

Развлечения > Звукозапись), входящей в стандартную поставку Windows. Однако лучше это делать специализированными средствами, например программой Sound Forge. Если открыть эту программу и нажать кнопку Record (Запись) или комбинацию клавиш CTRL+R, откроется окно записи нового файла (рис. 5.3). Если здесь установить флажок Monitor (Индика ция), то уровень входного сигнала будет виден на индикаторе. Включите самое громкое место в своей записи и, изменяя уровень входного сигнала с помощью ползункового регулятора в окне системного микшера (рис. 5.4), добейтесь того, чтобы на самых громких звуках уровень был приблизи тельно равен -1 дБ, то есть был близким к максимальному, но ни в коем

Рис. 5.3. Окно записи в программе Sound Forge

случае не превышал его. Превышение уровня записи индицируется в окне программы Sound Forge красной надписью Clip, как показано на рис. 5.4. Такого допускать нельзя, так как в этом случае в записи появятся неустранимые искажения.




Рис. 5.4. Индикация перегрузки

Когда уровень записи установлен, можно начинать запись. Для этого нажмите кнопку Record (Запись). Во время записи постоянно мигает красная надпись Recording. Когда нужный фрагмент записан, нажмите кнопку Stop (Остановить), а затем кнопку Close (Закрыть). Сохраните записанный файл на диске комбинацией клавиш CTRL+S.

Теперь несколько замечаний. Обычно запись с внешнего источника осуществляется с помощью линейного входа, как было описано выше. Однако на многих современных звуковых картах имеется цифровой интерфейс S/PDIF. Если он у вас есть и вы осуществляете запись с DAT-кассеты или минидиска, то посмотрите, возможно, ваш DAT- магнитофон или MD- проигрыватель тоже имеют такой интерфейс. В этом случае целесообразно записывать звук не через линейный вход, а именно через S/PDIF, так как в этом случае процесс записи внесет в звук гораздо меньше искажений.

У проигрывателей минидисков довольно редко можно встретить обычный коаксиальный разъем S/PDIF, однако, как правило, они оснащаются оптическим входом/выходом. У некоторых современных звуковых карт также имеется оптический вход, хотя это пока и редкость. Проверьте, и если есть такая возможность, записывайте звук через оптический интерфейс. Правда, для этого потребуется специальный кабель.


Запрос сведений у читателя


Как видите, нам не пришлось вручную заполнять все ячейки таблицы, мы ограничились вместо этого шестью изящными строками кода. Кроме того, если вам вдруг понадобится расширить таблицу, например организовать вывод значений вплоть до 20х20, это можно сделать, просто заменив два числа в коде (10 на 20). Более того, мы теперь можем дать пользователю

Рис. 6.4. Генерация таблицы “на лету”

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

mini = prompt ("Введите минимальное значение первого множителя", "2");

Здесь есть пояснение и поле для ввода, где уже приготовлено значение, принятое по умолчанию. И пояснение, и значение, принятое по умолчанию, необходимо указать при вызове метода prompt, как показано выше. Значение, введенное пользователем, будет присвоено переменной mini. Если пользователь нажмет кнопку Отмена, то этим значением будет null (так в JavaScript обозначается ничто, то есть отсутствие какого-либо значения).

Итак, с помощью метода prompt мы просим ввести значения (придется использовать этот метод 4 раза), присваиваем их переменным и подставляем эти переменные в условия цикла, например, так:

for (j=minl; j<=maxl; j++) document.write("<TD>"+j+"&times;"+i+"="+(i*j)+"</TD>");

<STYLE> BODY { text-align: center; background-color: #FCF7EC; }

TD { text-align: right; } </STYLE>

<BODY>

<Н2>ТАБЛИЦА ВОЗВЕДЕНИЯ В СТЕПЕНЬ</Н2>

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

<SCRIPT> <! -- var i,j; for (i=2; i<=10; i++) { document.write("<TR>") ; for (j=2; j<10; j++)

document.write("<TD>"+j+"<SOP>"+i+"</SUP>="+ Math.pow(j,i)+"</TD>") ;

document.write("</TR>") ;

} //-->

</SCRIPT>

</TABLE>

</BODY>

</HTML>

Если посмотреть внимательно, то можно заметить, что все отличие состоит в заголовках и строке записи ячейки. В ней мы использовали тег

<SUP>

для записи показателя степени. А для вычисления результата здесь исполь- зуется метод Math.pow, который, кстати, очень прост в использовании. Например, чтобы вычислить 5

7

, достаточно написать Math.pow(5,7).

Итак, в этом разделе были показаны примеры использования сценариев JavaScript. Ниже мы рассмотрим, как можно сократить количество кода, используя так называемые функции.



Звуковые гиперссылки


И наконец, еще один способ помещения музыки на веб-страницу заключается в простом создании гиперссылки на музыкальный файл (в атрибуте HREF=). Например, если написать

...А теперь послушайте

<А HREF="mymusic.mid">музыкy</A>!

то при нажатии на гиперссылку пользователь услышит звукозапись из заданного файла (после того как тот загрузится). В некоторых случаях броузер может выдать запрос, открывать ли ему этот файл с текущего места (то есть, проигрывать ли его сразу), или же просто сохранить на жестком диске. А иногда броузер может запросить указание на приложение, с помощью которого данный файл должен воспроизводиться. Если музыкальная информация действительно важна, следует пользоваться именно этим способом, поскольку в самом крайнем случае пользователь всегда сможет просто сохранить файл на диск, а потом уже прослушивать его с помощью других npогpaмм.



Звуковые объекты


Другой способ помещения музыкального объекта на страничку заключается в применении более универсального тега

<OBJECT>

. Вообще говоря, этот тег может использоваться не только для встраивания звуковых объектов. Он появился в свое время в Internet Explorer для встраивания объектов ActiveX/COM (что было альтернативой возможности запуска Java-апплетов в броузерах Netscape с помощью тега

<APPLET>

). Если музыкальный объект размещен на веб-странице с помощью тега

<OBJECT>

, броузер в некоторых случаях может сообщить об отсутствии средств воспроизведения файлов такого типа. Иногда это вызывает удивление, так как те же файлы прекрасно воспроизводятся на том же компьютере, однако здесь требуется не любое средство воспроизведения, а только встроенное в данный броузер. В таких случаях необходимо доустановить модуль просмотра в броузер (может быть, предварительно загрузив его из Интернета).

Для помещения музыкального объекта на страничку используется такой синтаксис тега

<OBJECT>:

<OBJECT DATA="SOUNDS/MyI')OLLY.mp3" TYPE="audio/wav">

</OBJECT>

Как видите, атрибут DATA= определяет файл — источник музыки, а атрибут TYPE= определяет его тип (формат). О форматах мы поговорим ниже.

Если при использовании тега

<BGSOUND>

музыка исполняется в качестве фона, то при использовании тега

<OBJECT>

объект можно наблюдать на экране, как правило, в виде встроенного проигрывателя с кнопками Пуск, Стоп и другими элементами управления. Поэтому для тега

<OBJECT>

возможно использование таких атрибутов, как ALIGN= (со значениями top, middle, bottom, left, right), WIDTH=, HEIGHT=, HSPACE=, VSPACE= и даже USEMAP=. Все эти атрибуты нам уже знакомы по тегу <IMG>. Кстати, с помощью тега

<OBJECT>

действительно можно вставлять в тексты веб-страниц графические объекты и видеоклипы. При этом список форматов существенно расширяется (например, можно просматривать картинки в форман тах TIFF и WMF), лишь бы только к броузеру был подключен соответствующий модуль просмотра.
Кстати, можно вкладывать несколько элементов

<OBJECT>

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

<OBJECT DATA="MyClip.mpg" TYPE="video/x-mpeg">

<OBJECT DATA="MySound.aiff" TYPE="audio/x-aiff">

<OBJECT DATA="MyPicturel.tiff" TYPE="image/tiff">

<OBJECT DATA="MyPicture2.gif" TYPE="image/gif"> Здесь должен быть видеоклип... </OBJECT> </OBJECT> </OBJECT> </OBJECT>

В этом примере броузер сначала попытается воспроизвести видеоклип (файл в формате MPEG). Если это ему удастся, то все, что находится внутри данного тега, игнорируется, а если нет — броузер попытается воспроизвести музыкальный файл в формате АIFF. Если же он не найдет модуля вос произведения и для этого файла, он попытается отобразить рисунок в формате TIFF, а уж если и это не получится, то в формате GIF. При таком невероятном стечении обстоятельств, что броузеру и это не удастся сделать, на месте объекта будет просто отображен текст Здесь должен быть

видеоклип... И еще один момент. В теге

<OBJECT>

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

<OBJECT DATA="sound.wav" TYPE="audio/wav" STANDBY="3arpyжаю звуковой объект, подождите немного...">

Если файл sound, wav имеет достаточно большой размер, пользователь уви дит на экране надпись о происходящей загрузке.