Глава 9. JavaScript: баловство или необходимость?

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

Самый главный скрипт

Наша борьба с таблицами в предыдущей главе вскрыла одну из важнейших проблем html-писателей: всё, что мы напишем, будет просматриваться пользователями не в идеальной среде, а на конкретных браузерах (от англ. browser - «браузер», обозреватель). То есть все спецификации - HMTL, CSS - это набор неких «усреднённых» правил, которые должны работать (являются рекомендациями). Но у разработчиков веб-обозревателей есть свои представления о том, как следует трактовать написанные нами html-тэги и правила CSS.

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

Вот как можно получить информацию о браузере:

var agent = navigator.userAgent.toLowerCase(); document.write(agent);

Запишите этот код в файл browsr01.html (файл есть на CD в папке omne\js1, а также по адресу: omne/js1) и откройте файл в браузере. Интернет Эксплорер версии 5 напечатает на вашей странице следующую строчку:

mozilla/4.0 (compatible; msie 5.01; windows nt 5.0)

Браузер Mozilla Firefox - другую:

mozilla/5.0 (windows; u; windows nt 5.0; ru; rv:1.8) gecko/20051111 firefox/1.5

Мы смотрим на две разные строки и, анализируя их содержание, находим разницу. Примерно то же самое можно делать с помощью программы, написанной на JavaScript: надо специальной функцией проанализировать, распознать полученную строку, которую мы занесли в переменную agent. Эта функция (на самом деле не функция, а метод объекта String, но пока это неважно) называется indexOf() и используется так: Строка1.indexOf(Строка2). «Строка1» - строка, в которой надо найти последовательность символов; «Строка2» - последовательность символов, которую мы хотим найти в «Строке1». Важно подобрать правильное слово для поиска. Если мы для идентификации браузера будем искать, например, слово mozilla , то не сможем отличить IE от Firefox, потому что в обеих строчках искомое слово есть. Поэтому для опознания IE будем искать в названии браузера слово msie , а для опознания Firefox или SeaMonkey - слово gecko . Добавьте к первоначальному коду скрипта следующие строчки и сохраните новый текст в файле browsr02.html:

If (agent.indexOf("msie") > -1) document.write("
Internet Explorer"); if (agent.indexOf("gecko") > -1) document.write("
Gecko");

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

Распознавание браузера необходимо не только для коррекции очень сложного веб-дизайна, но и для обычной, отнюдь не затейливой html-вёрстки (размещения текстов и картинок на странице). Разные браузеры могут отображать по-разному даже очень простой фрагмент. Допустим, мы решили заключить в рамку определённого размера один заголовок и один абзац из этой книги, и в предварительной отладке использовали Firefox. После несложной работы (результат - файлы browsr03.html и js1.css) мы в этом самом Firefox"е видим то, что хотели получить и успокаиваемся:

Глава 1. Создание вашей первой HTML-страницы

Потом мы (так, на всякий случай - ведь на странице не было ничего такого !) открываем тот же файл в Интернет Эксплорере, и вдруг видим, что наша простая вёрстка из двух абзацев куда-то «поехала»:

Глава 1. Создание вашей первой HTML- страницы

Что мешает вам создать веб-сайт и поместить его в Интернет? На этот вопрос можно найти довольно много ответов. Точнее, можно найти много причин, по которым создание интернет-страницы кажется вам невероятно сложной задачей.

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

Наш фрагмент отображается в обозревателях по-разному, потому что Интернет Эксплорер считает ширину блочных элементов вместе с величиной padding и толщиной border , а Gecko (и Opera) исключают из размера блока padding и border . В стилевом файле js1.css мы задали ширину раздела div.b1 в 29em, а когда добавили к этому разделу рамку и отступы содержимого от краёв (padding), обозреватели Gecko оставили ширину полезной площади прежней - 29em и дорисовали отступы в 1em и рамку толщиной 0.4em вокруг раздела, увеличив тем самым его общую ширину на 2.8em. Интернет Эксплорер же втиснул рамку в заданную ширину 29em, чем фактически уменьшил ширину полезной площади на 2.8em. Вот строчки и «поехали»...

Дело, очевидно, можно исправить, увеличив ширину раздела div.b1 на ушедшие на рамку и padding 2.8em, то есть задав её в 31.8em. Тогда в IE заголовок уместится в одну строку, и остальной текст будет выглядеть, как задумано. Но в Gecko ширина раздела тоже увеличится на 2.8em (а она уже была нормальной) - и строчки опять «поползут». Вот примерно для таких случаев и существует решение - с помощью скрипта привязывать к странице разные CSS-файлы, в зависимости от типа браузера. Создайте новый стилевой файл js2.css с точно таким же содержимым, что и в js1.css, затем измените в нём ширину раздела div.b1 с 29em на 31.8em. Добавьте также в файле js1.css (для обозревателей Gecko) к правилам для body font-size :16px - таково в IE значение размера шрифта по умолчанию, такой же размер должен быть и в других браузерах (значение по умолчанию в них не совпадает со значением в IE). Затем создайте новый файл browsr04.html с точно таким же содержимым, как в browsr03.html, и переделайте скрипт в файле browsr04.html на следующий:

var agent = navigator.userAgent.toLowerCase(); if (agent.indexOf("gecko") > -1) document.write(""); if (agent.indexOf("msie") > -1) document.write(""); else document.write("");

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

Как это работает

Скрипт - это, скорее, жаргонное название, по-научному его обычно называют «сценарием» (от англ. script - «сценарий»). Так вот, скрипт начинает работать по той же причине, по которой расставленные вами html-тэги и записанные правила CSS превращаются в видимые глазом изменения шрифта и цвета страницы. Эта причина - браузер: когда программа просмотра интернет-страниц находит в html-тексте метку , она (программа) делает на экране абзацный отступ по правилам, найденным ею в соответствующем файле CSS. Когда браузер находит в тексте html-страницы метки ..., всё, что находится между этими метками, он рассматривает как команды, написанные на языке JavaScript, и пытается эти команды выполнить.

Например, если мы запишем в html-текст (между соответствующими обозначениями начала и конца скрипта) команду скрипта document.write(«Привет!»), браузер при открытии документа выведет на экран слово «Привет!».

Так же можно заставить браузер вставить в текст страницы невидимую глазом запись , привязывающую к странице файл CSS. Эта запись получается невидимой по самой своей природе: браузеры обучены рассматривать текст, заключённый в тэге , как определённую инструкцию, не предназначенную для вывода на экран. Невидимая на экране команда JavaScript вставляет в текст страницы невидимую глазом инструкцию - и вид страницы изменяется. Всё просто.

Красота решения

На языках HMTL, JavaScript, так же, как и на русском языке, можно описать одни и те же предметы по-разному. Мы не планируем в этой книге вдаваться в стилистические тонкости, поэтому понятие «по-разному» попытаемся конкретизировать, сузить. Мы будем считать, что разные решения возникают, в основном, от борьбы двух тенденций, двух не всегда осознаваемых устремлений человека: 1) экономия мыслительных усилий; 2) экономия материала. Например, у меня в голове (или в душе?) такая борьба началась в тот самый момент, как я написал для этой книги скрипт, позволяющий менять оформление страницы в зависимости от браузера.

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

Если посмотреть на текст скрипта из файла browsr04.html повнимательней, можно заметить, что строчка «document.write("");» повторяется в нём три раза почти без изменений. Отличаются эти три строки только одной цифрой в имени файла: js1.css - js2.css. Возникает вопрос: нельзя ли эту строчку записать только один раз, в конце скрипта, а цифру представить каким-нибудь хитрым образом, чтобы она прямо при записи менялась в зависимости от обстоятельств. Ответ: на то и существуют переменные.

Объявим в начале нашего скрипта с помощью волшебного слова var переменную i :

var i; (каждое «действие» в сценарии JavaScript должно заканчиваться знаком; - точка с запятой).

Самую последнюю строчку, печатающую результат в файл, сделаем такой:

Document.write("");

Знак + в данном случае соединяет в единую строку несколько разных фрагментов текста. Если бы мы, например, написали строку «2 + 2», JavaScript заставил бы браузер вывести на экран «4» (а не «22»). Но мы записываем "js" + 2 + ".css", и получим в итоге "js2.css". Обратите внимание на то, как расставлены кавычки. Все текстовые строки в JavaScript должны быть заключены в кавычки - всё равно, в какие: двойные или одинарные. Мы выбрали двойные. Но в результирующей строке языка HTML тоже нужны кавычки, и если мы попытаемся написать "document.write("