Введение в JavaScript

Cвойства

Многие HTML-контейнеры имеют атрибуты. Например, контейнер якоря ... имеет атрибут HREF, который превращает его в гипертекстовую ссылку:
intuit
Если рассматривать контейнер якоря ... как объект, то атрибут HREF будет задавать свойство   объекта "якорь". Программист может изменить значение атрибута и, следовательно, свойство   объекта:
document.links[0].href="intuit.htm";
Не у всех атрибутов можно изменять значения. Например, высота и ширина графической картинки определяются по первой загруженной в момент отображения страницы картинке. Все последующие картинки, которые заменяют начальную, масштабируются до нее. Справедливости ради следует заметить, что в Microsoft Internet Explorer размер картинки может меняться.
Для общности картины свойствами в JavaScript наделены объекты, которые не имеют аналогов в HTML-разметке. Например, среда исполнения, называемая объектом   Navigator, или окно браузера, которое является вообще самым старшим объектом   JavaScript.

Иерархия классов

Объектно-ориентированный язык программирования предполагает наличие иерархии классов объектов. В JavaScript такая иерархия начинается с класса объектов   Window, т.е. каждый объект приписан к тому или иному окну. Для обращения к любому объекту или его свойству указывают полное или частичное имя этого объекта или свойства   объекта, начиная с имени объекта старшего в иерархии, в который входит данный объект:
Иерархия классов
13.2.
Сразу оговоримся, что приведенная нами схема объектной модели верна для Netscape Navigator версии 4 и выше, а также для Microsoft Internet Explorer версии 4 и выше. Еще раз отметим, что объектные модели у Internet Explorer и Netscape Navigator совершенно разные, а приведенная схема составлена на основе их общей части.
Вообще говоря, JavaScript не является классическим объектным языком (его еще называют облегченным объектным языком). В нем нет наследования и полиморфизма. Программист может определить собственный класс объектов через оператор function, но чаще пользуется стандартными объектами, их конструкторами и вообще не применяет деструкторы классов. Это объясняется тем, что область действия JavaScript-программы обычно не распространяется за пределы текущего окна.
Иногда у разных объектов   JavaScript бывают определены свойства с одинаковыми именами. В этом случае нужно четко указывать, свойство какого объекта программист хочет использовать. Например, Window и Document имеют свойство location. Только для Window это объект класса Location, а для Document - строковый литерал, который принимает в качестве значения URL загруженного документа.
Следует также учитывать, что для многих объектов существуют стандартные методы преобразования значений свойств   объектов в обычные переменные. Например, для всех объектов по умолчанию определен метод преобразования в строку символов: toString(). В примере с location, если обратиться к window.location в строковом контексте, будет выполнено преобразование по умолчанию, и программист этого не заметит:


Методы

В терминологии JavaScript   методы   объекта определяют функции изменения его свойств. Например, с объектом "документ" связаны методы   open(), write(), close(). Эти методы позволяют сгенерировать или изменить содержание документа. Приведем простой пример:
function hello() { id=window.open("","example","width=400, height=150"); id.focus(); id.document.open(); id.document.write("

Привет!

"); id.document.write("
"); id.document.write(""); id.document.close(); }
В этом примере метод   open() открывает поток записи в документ, метод   write() осуществляет эту запись, метод   close() закрывает поток записи в документ. Все происходит так же, как и при записи в обычный файл. Если у окна есть поле статуса (обычно в нем отображается уровень загрузки документа), то при незакрытом потоке записи в документ в нем будет "метаться" прямоугольник продолжения записи, как это происходит при загрузке документа.

Обработчики событий

Такие программы, как обработчики событий (handler), указываются в атрибутах контейнеров, с которыми эти события связаны. Например, при нажатии на кнопку происходит событие click:

Подстановки

Подстановка (entity) встречается на Web-страницах довольно редко. Тем не менее это достаточно мощный инструмент генерации HTML-страницы на стороне браузера. Подстановки используются в качестве значений атрибутов HTML-контейнеров. Например, как значение по умолчанию поля формы, определяющего домашнюю страницу пользователя, будет указан URL текущей страницы:
... Тело документа ...
HTML-комментарии здесь вставлены для защиты от интерпретации данного фрагмента страницы HTML-парсером в старых браузерах (у высокого начальства еще встречаются). В свою очередь, конец HTML-комментария защищен от интерпретации JavaScript-интерпретатором (// в начале строки). Кроме того, в качестве значения атрибута LANGUAGE у тега начала контейнера указано значение "JavaScript". VBScript, который является альтернативой JavaScript - это скорее экзотика, чем общепринятая практика, поэтому данный атрибут можно опустить - значение "JavaScript" принимается по умолчанию.
Очевидно, что размещать в заголовке документа генерацию текста страницы бессмысленно - он не будет отображен браузером. Поэтому в заголовок помещают декларации общих переменных и функций, которые будут затем использоваться в теле документа. При этом браузер Netscape Navigator более требовательный, чем Internet Explorer. Если не разместить описание функции в заголовке, то при ее вызове в теле документа можно получить сообщение о том, что данная функция не определена.
Приведем пример размещения и использования функции:

Часы в строке статуса


В Internet Explorer 4.0 подстановки не поддерживаются, поэтому пользоваться ими следует аккуратно. Прежде чем выдать браузеру страницу с подстановками, нужно проверить тип этого браузера.
В случае подстановки интерпретатор получает управление в момент разбора браузером (компонент парсер) HTML-документа. Как только парсер встречает конструкцию &{..} у атрибута контейнера, он передает управление интерпретатору JavaScript, который, в свою очередь, после исполнения кода это управление возвращает парсеру. Таким образом данная операция аналогична подкачке графики на HTML-страницу.

Понятие объектной модели применительно к JavaScript

Для создания механизма управления страницами на клиентской стороне было предложено использовать объектную модель документа. Суть модели в том, что каждый HTML-контейнер - это объект, который характеризуется тройкой:
  • свойства
  • методы
  • события

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

    Размещение кода на HTML-странице

    Главный вопрос любого начинающего программиста: "Как оформить программу и выполнить ее?". Попробуем на него ответить как можно проще, но при этом не забывая обо всех способах применения JavaScript-кода.
    Во-первых, исполняет JavaScript-код браузер. В него встроен интерпретатор JavaScript. Следовательно, выполнение программы зависит от того, когда и как этот интерпретатор получает управление. Это, в свою очередь, зависит от функционального применения кода. В общем случае можно выделить четыре способа функционального применения JavaScript:
  • гипертекстовая ссылка (схема URL);
  • обработчик события (handler);
  • подстановка (entity) (в Microsoft Internet Explorer реализована в версиях от 5.X и выше);
  • вставка (контейнер SCRIPT).

  • В учебниках по JavaScript описание применения JavaScript обычно начинают с контейнера SCRIPT. Но с точки зрения программирования это не совсем правильно, поскольку такой порядок не дает ответа на ключевой вопрос: как JavaScript-код получает управление? То есть каким образом вызывается и исполняется программа, написанная на JavaScript и размещенная в HTML-документе.
    В зависимости от профессии автора HTML-страницы и уровня его знакомства с основами программирования возможны несколько вариантов начала освоения JavaScript. Если вы программист классического толка (С, Fortran, Pascal и т.п.), то проще всего начинать с программирования внутри тела документа, если вы привыкли программировать под Windows, то в этом случае начинайте с программирования обработчиков событий, если вы имеете только опыт HTML-разметки или давно не писали программ, то тогда лучше начать с программирования гипертекстовых переходов.

    Размещение кода внутри HTML-документа

    Собственно, особенного разнообразия здесь нет. Код можно разместить либо в заголовке документа, внутри контейнера HEAD, либо внутри BODY. Последний способ и его особенности будут рассмотрены в разделе "Условная генерация HTML-разметки на стороне браузера". Поэтому обратимся к заголовку документа.
    Код в заголовке размещается внутри контейнера SCRIPT:

    Часы в строке статуса


    В этом примере мы декларировали функцию time_scroll() в заголовке документа, а потом вызвали ее как обработчик события load в теге начала контейнера BODY (onLoad=time_scroll()) .
    В качестве примера декларации переменной рассмотрим изменение статуса окна-потомка из окна-предка:
    Создадим дочернее окно с помощью следующей функции, продекларировав ее, а затем и вызвав:
    function sel() { id = window.open("","example","width=500,height=200,status,menu"); id.focus(); id.document.open(); id.document.write(" "); id.document.write(""); id.document.write("
    "); id.document.write("

    Change text into child window.

    "); id.document.write("
    "); id.document.write(""); id.document.write("
    "); id.document.write("
    "); id.document.write(""); id.document.close(); }
    Открывая окно-потомок, мы поместили в переменную id указатель на объект окно id=window.open(). Теперь мы можем использовать ее как идентификатор объекта класса Window. Использование id.focus() в нашем случае обязательно. При нажатии на кнопку "Изменить поле статуса в окне примера" происходит передача фокуса в родительское окно. Оно может иметь размер экрана. При этом изменения будут происходить в окне-потомке, которое будет скрыто родительским окном. Для того чтобы увидеть изменения, надо передать фокус. Переменная id должна быть определена за пределами каких-либо функций, что и сделано. В этом случае она становится свойством окна. Если мы поместим ее внутри функции открытия дочернего окна, то не сможем к ней обратиться из обработчика события click.

    объекты характеризуются событиями. Собственно, суть

    Кроме методов и свойств   объекты характеризуются событиями. Собственно, суть программирования на JavaScript заключается в написании обработчиков этих событий. Например, с объектом типа button (контейнер INPUT типа button - "Кнопка") может происходить событие click, т.е. пользователь может нажать на кнопку. Для этого атрибуты контейнера INPUT расширены атрибутом обработки события click - onClick. В качестве значения этого атрибута указывается программа обработки события, которую должен написать на JavaScript автор HTML-документа:

    Обработчики событий указываются в тех контейнерах, с которыми эти события связаны. Например, контейнер BODY определяет свойства всего документа, поэтому обработчик события завершения загрузки всего документа указывается в этом контейнере как значение атрибута onLoad.
    Примечание. Строго говоря, каждый браузер, будь то Internet Explorer, Netscape Navigator или Opera, имеет свою объектную модель. Объектные модели разных браузеров (и даже разные версии одного) отличаются друг от друга, но имеют принципиально одинаковую структуру. Поэтому нет смысла останавливаться на каждой из них по отдельности. Мы будем рассматривать общий подход применительно ко всем браузерам, иногда, конечно, заостряя внимание на различиях между ними.

    URL-схема JavaScript

    Схема URL (Uniform Resource Locator) - это один из основных элементов Web-технологии. Каждый информационный ресурс в Web имеет свой уникальный URL. URL указывают в атрибуте HREF контейнера A, в атрибуте SRC контейнера IMG, в атрибуте ACTION контейнера FORM и т.п. Все URL подразделяются на схемы доступа, которые зависят от протокола доступа к ресурсу, например, для доступа к FTP-архиву применяется схема ftp, для доступа к Gopher-архиву - схема gopher, для отправки электронной почты - схема smtp. Тип схемы определяется по первому компоненту URL: http://intuit.ru/directory/page.html
    В данном случае URL начинается с http - это и есть определение схемы доступа (схема http).
    Основной задачей языка программирования гипертекстовой системы является программирование гипертекстовых переходов. Это означает, что при выборе той или иной гипертекстовой ссылки вызывается программа реализации гипертекстового перехода. В Web-технологии стандартной программой является программа загрузки страницы. JavaScript позволяет поменять стандартную программу на программу пользователя. Для того чтобы отличить стандартный переход по протоколу HTTP от перехода, программируемого на JavaScript, разработчики языка ввели новую схему URL - JavaScript:
    ...
    В данном случае текст "JavaScript_код" обозначает программы-обработчики на JavaScript, которые вызываются при выборе гипертекстовой ссылки в первом случае и при загрузке картинки - во втором.
    Например, при нажатии на гипертекстовую ссылку Внимание!!! можно получить окно предупреждения:
    Внимание!!!
    URL-схема JavaScript
    Рис. 13.1.. 
    А при нажатии на кнопку типа submit в форме можно заполнить текстовое поле этой же формы:

    В URL можно размещать сложные программы и вызовы функций. Следует только помнить, что схема JavaScript работает не во всех браузерах, а только в версиях Netscape Navigator и Internet Explorer, начиная с четвертой.
    Таким образом при программировании гипертекстового перехода интерпретатор получает управление после того, как пользователь "кликнул" по гипертекстовой ссылке.

    Условная генерация HTML-разметки на стороне браузера

    Всегда приятно получать с сервера страницу, подстроенную под возможности нашего браузера или, более того, под пользователя. Существует только две возможности генерации таких страниц: на стороне сервера или непосредственно у клиента. JavaScript-код исполняется на стороне клиента (на самом деле, серверы компании Netscape способны исполнять JavaScript-код и на стороне сервера, только в этом случае он носит название LiveWire-код; не путать с LiveConnect), поэтому рассмотрим только генерацию на стороне клиента.
    Для генерации HTML-разметки контейнер SCRIPT размещают в теле документа. Простой пример - встраивание в страницу локального времени:
    ... ...

    Вставка (контейнер SCRIPT - принудительный вызов интерпретатора)

    Контейнер SCRIPT - это развитие подстановок до возможности генерации текста документа JavaScript-кодом. В этом смысле применение SCRIPT аналогично Server Side Includes, т.е. генерации страниц документов на стороне сервера. Однако здесь мы забежали чуть вперед. При разборе документа HTML-парсер передает управление интерпретатору после того, как встретит тег начала контейнера SCRIPT. Интерпретатор получает на исполнение весь фрагмент кода внутри контейнера SCRIPT и возвращает управление HTML-парсеру для обработки текста страницы после тега конца контейнера SCRIPT.
    Контейнер SCRIPT выполняет две основные функции:
  • размещение кода внутри HTML-документа;
  • условная генерация HTML-разметки на стороне браузера.

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

    Вступление

    Гипертекстовая информационная система состоит из множества информационных узлов, множества гипертекстовых связей, определенных на этих узлах и инструментах манипулирования узлами и связями. Технология World Wide Web - это технология ведения гипертекстовых распределенных систем в Internet, и, следовательно, она должна соответствовать общему определению таких систем. Это означает, что все перечисленные выше компоненты гипертекстовой системы должны быть и в Web.
    Web, как гипертекстовую систему, можно рассматривать с двух точек зрения. Во-первых, как совокупность отображаемых страниц, связанных гипертекстовыми переходами (ссылками - контейнер ANCHOR). Во-вторых, как множество элементарных информационных объектов, составляющих отображаемые страницы (текст, графика, мобильный код и т.п.). В последнем случае множество гипертекстовых переходов страницы - это такой же информационный фрагмент, как и встроенная в текст картинка.
    При втором подходе гипертекстовая сеть определяется на множестве элементарных информационных объектов самими HTML-страницами, которые и играют роль гипертекстовых связей. Этот подход более продуктивен с точки зрения построения отображаемых страниц "на лету" из готовых компонентов.
    При генерации страниц в Web возникает дилемма, связанная с архитектурой "клиент-сервер". Страницы можно генерировать как на стороне клиента, так и на стороне сервера. В 1995 году специалисты компании Netscape создали механизм управления страницами на клиентской стороне, разработав язык программирования JavaScript.
    Таким образом, JavaScript - это язык управления сценариями просмотра гипертекстовых страниц Web на стороне клиента. Если быть более точным, то JavaScript - это не только язык программирования на стороне клиента. Liveware, прародитель JavaScript, является средством подстановок на стороне сервера Netscape. Однако наибольшую популярность JavaScript обеспечило программирование на стороне клиента.
    Основная идея JavaScript состоит в возможности изменения значений атрибутов HTML-контейнеров и свойств среды отображения в процессе просмотра HTML-страницы пользователем. При этом перезагрузки страницы не происходит.
    На практике это выражается в том, что можно, например, изменить цвет фона страницы или интегрированную в документ картинку, открыть новое окно или выдать предупреждение.
    Название "JavaScript" является собственностью Netscape. Реализация языка, осуществленная разработчиками Microsoft, официально называется Jscript. Версии JScript совместимы (если быть совсем точным, то не до конца) с соответствующими версиями JavaScript, т.е. JavaScript является подмножеством языка JScript.
    JavaScript стандартизован ECMA (European Computer Manufacturers Association - Ассоциация европейских производителей компьютеров). Соответствующие стандарты носят названия ECMA-262 и ISO-16262. Этими стандартами определяется язык ECMAScript, который примерно эквивалентен JavaScript 1.1. Отметим, что не все реализации JavaScript на сегодня полностью соответствуют стандарту ECMA. В рамках данного курса мы во всех случаях будем использовать название JavaScript.

    Введение в JavaScript

    Фреймы (Frames)

    Фреймы — это несколько видоизмененные окна. Отличаются они от обычных окон тем, что размещаются внутри них. У фрейма не может быть ни панели инструментов, ни меню, как в обычном окне. В качестве поля статуса фрейм использует поле статуса окна, в котором он размещен. Существует и ряд других отличий.
    Мы остановимся на:
  • иерархии фреймов;
  • именовании фреймов;
  • передаче данных во фрейм.

  • Естественно, что иерархия определяет и правила именования фреймов, и способы передачи фокуса фрейму.

    Иерархия фреймов

    Рассмотрим сначала простой пример. Разделим экран на две вертикальные колонки: (открыть)

    Иерархия фреймов
    Рис. 14.3.  Фрейм с двумя вертикальными колонками
    Назовем окно, в которое помещают фреймы, _top(_parent).
    Усложним пример: разобьем правый фрейм на два по горизонтали: (открыть)

    Иерархия фреймов
    Рис. 14.4.  Правый фрейм, разбитый на два по горизонтали
    Обратите внимание на два момента: во-первых, следует различать _top и top, во-вторых, исчез фрейм   right. По поводу первого замечания: _top — это зарезервированное имя старшего окна, а top — имя фрейма, которое назначил ему автор страницы. По поводу второго замечания: старшим окном для всех фреймов является все окно браузера, фрейма с именем right в данном случае не существует.
    Для того чтобы он появился, нужно свести оба наших примера в один. Это значит, что во фрейм   right мы снова должны загрузить фреймовый документ.
    Первый документ:

    Второй документ (right.htm):

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

    Именование фреймов

    Обратиться к фрейму можно либо по имени, либо как к элементу массива frames[]. Рассмотрим HTML-документ:
    ...
    Предположим, что на странице, загруженной в правый фрейм, есть две картинки. Для изменения свойства src второй из них можно использовать следующие записи:
    top.frames[1].images[1].src="pic.gif";
    или
    top.right.images[1].src="pic.gif";
    В связи с индексированием фреймов возникает вопрос о том, как они нумеруются в одномерном встроенном массиве фреймов объекта Window. Проиллюстрируем это на примере: (открыть)

    Именование фреймов
    Рис. 14.5.  Центральный фрейм, разбитый на три вертикальных
    Построим теперь нечто перпендикулярное предыдущему примеру – столбец из трех фреймов: (открыть)

    Именование фреймов
    Рис. 14.6.  Центральный фрейм, разбитый на три горизонтальных
    Таким образом, при нумеровании фреймов в одномерном массиве фреймов на странице система придерживается правила "слева направо, сверху вниз". Вкладывая наши примеры друг в друга, можно получить правильную индексацию страниц при любой сложной фреймовой структуре.

    История посещений (History)

    История посещений (трасса) страниц World Wide Web позволяет пользователю вернуться к странице, которую он просматривал несколько минут (часов, дней) назад. История посещений в JavaScript трансформируется в объект класса history. Этот объект указывает на массив URL-страниц, которые пользователь посещал и которые он может получить, выбрав из меню браузера режим GO. Методы объекта history позволяют загружать страницы, используя URL из этого массива.
    Чтобы не возникло проблем с безопасностью браузера, путешествовать по History можно, только используя индекс URL. При этом URL, как текстовая строка, программисту недоступен. Чаще всего этот объект используют в примерах или страницах, на которые могут быть ссылки из нескольких разных страниц, предполагая, что можно вернутся к странице, из которой пример будет загружен:

    Данный код отображает кнопку "Назад", нажав на которую мы вернемся на предыдущую страницу.

    Методы

    Методы Location предназначены для управления загрузкой и перезагрузкой страницы. Это управление заключается в том, что можно либо перезагрузить документ (reload), либо загрузить (replace). При этом в историю просмотра страниц (history) информация не заносится:
    window.location.reload(true); window.location.replace('#top');
    Метод reload() полностью моделирует поведение браузера при нажатии на кнопку Reload в панели инструментов. Если вызывать метод без аргумента или указать его равным true, то браузер проверит время последней модификации документа и загрузит его либо из кеша (если документ не был модифицирован), либо с сервера. Такое поведение соответствует простому нажатию на кнопку Reload. Если в качестве аргумента указать false, то браузер перезагрузит текущий документ с сервера, несмотря ни на что. Такое поведение соответствует одновременному нажатию на Reload и кнопку клавиатуры Shift (Reload+Shift).
    Метод replace() позволяет заменить одну страницу другой таким образом, что это замещение не будет отражено в трассе просмотра HTML-страниц (history), и при нажатии на кнопку Back из панели инструментов пользователь всегда будет попадать на первую загруженную обычным способом (по гипертекстовой ссылке) страницу. Напомним, что при изменении свойств Location также происходит перезагрузка страниц, но в этом случае записи об их посещении в history пропадают.

    Передача фокуса во фрейм

    Обычной задачей при разработке типового Web-узла является загрузка результатов исполнения CGI-скрипта во фрейм, отличный от фрейма, в котором вводятся данные для этого скрипта. Если путь загрузки результатов фиксированный, то можно просто использовать атрибут TARGET формы. Сложнее, если результат работы должен быть загружен в разные фреймы, в зависимости от выбранной кнопки, например.
    Эту задачу можно решать по-разному: открывать ранее открытое окно или переназначать свойство target. Последнее решение, конечно, более изящное, с него и начнем:
    Листинг 14.8.
    (html, txt)
    Функция load() вызывается как обработчик события submit, она является логической функцией. Возврат значения true позволяет реализовать перезагрузку документа.
    Теперь рассмотрим второй вариант. Его идея состоит в том, что при попытке открыть окно с именем существующего окна новое окно не открывается, а используется уже открытое. Фрейм — это тоже окно, поэтому на него данное правило распространяется, но вот функция, которая реализует этот вариант, отличается от предыдущей:
    Листинг 14.9.
    (html, txt)
    Обратите внимание на то, что данная функция возвращает значение false. Это происходит потому, что надо маскировать событие submit. Ведь документ уже перезагружен и снова его загружать не надо.
    on_load_lecture()
    Передача фокуса во фрейм Передача фокуса во фрейм Перейти к вопросам "
    Передача фокуса во фрейм Если Вы заметили ошибку - сообщите нам. Передача фокуса во фрейм Страницы:
    " |
    1
    |
    2
    |
    3
    |
    вопросы | "
    |
    учебники
    |
    для печати и PDA
    Передача фокуса во фрейм Передача фокуса во фрейм Передача фокуса во фрейм
    Курсы | Учебные программы | Учебники | Новости | Форум | Помощь

    Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru

    © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование


    Поле location

    В поле location отображается URL загруженного документа. Если пользователь хочет вручную перейти к какой-либо странице (набрать ее URL), он делает это в поле location. Поле располагается в верхней части окна браузера ниже панели инструментов, но выше панели личных предпочтений.
    Поле location
    Рис. 14.2.  Поле Location
    Вообще говоря, Location — это объект. Из-за изменений в версиях JavaScript класс Location входит как подкласс и в класс Window, и в класс Document. Мы будем рассматривать Location только как window.location. Кроме того, Location — это еще и подкласс класса URL, к которому относятся также объекты классов Area и Link. Location наследует все свойства URL, что позволяет получить доступ к любой части схемы URL.
    Рассмотрим характеристики и способы использования объекта Location:
  • свойства;
  • методы;
  • событий, характеризующих Location, нет.

  • Как мы видим, список характеристик объекта Location неполный.

    Поле статуса

    Поле статуса — это первое, что начали использовать авторы HTML-страниц из арсенала JavaScript. Калькуляторы, игры, математические вычисления и другие элементы выглядели слишком искусственно. На их фоне бегущая строка в поле статуса была изюминкой, которая могла действительно привлечь внимание пользователей к Web-узлу. Постепенно ее популярность сошла на нет. Бегущие строки стали редкостью, но программирование поля статуса встречается на многих Web-узлах.
    Поле статуса
    Рис. 14.1.  Поле статуса
    Полем статуса (status bar) называют среднее поле нижней части окна браузера сразу под областью отображения HTML-страницы. В поле статуса отображается информация о состоянии браузера (загрузка документа, загрузка графики, завершение загрузки, запуск апплета и т.п.). Программа на JavaScript имеет возможность работать с этим полем как с изменяемым свойством окна. При этом фактически с ним связаны два разных свойства:
  • window.status;
  • window.defaultStatus.

  • Разница между ними заключается в том, что браузер на самом деле имеет несколько состояний, связанных с некоторыми событиями. Состояние браузера отражается в сообщении в поле статуса. По большому счету, существует только два состояния: нет никаких событий (defaultStatus) и происходят какие-то события (status).

    Microsoft Internet Explorer

    navigator.appName = Microsoft Internet Explorer navigator.appCodeName = Mozilla navigator.appVersion = 4.0 (compatible; MSIE 5.5; Windows 98) navigator.userAgent = Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)
    Листинг 14.1.
    Закрыть окно

    Листинг 14.2.
    Закрыть окно

    Листинг 14.3.
    Закрыть окно

    Листинг 14.4.
    Закрыть окно

    function myfocus(a) { id = window.open("","example","scrollbars,width=300,height=200"); //открываем окно и заводим переменную с указателем на него //если окно с таким именем существует, то новое окно не создается, //а открывается поток для записи в окно с этим именем if(a==1) { id.document.open(); //открываем поток ввода в уже созданное окно id.document.write("
    >Открыли окно в первый раз"); //Пишем в этот поток } if(a==2) { id.document.open(); id.document.write("
    Открыли окно во второй раз"); } if(a==3) { id.focus(); //передаем фокус, затем выполняем те же действия, что и в предыдущем случае id.document.open(); id.document.write("
    Открыли окно в третий раз"); } id.document.write("
    "); id.document.close(); }
    Листинг 14.5.
    Закрыть окно

    var flag= 0; var idp=null; function myclock() { if(flag==1) { d = new Date(); window.document.c.f.value = d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(); } idp=setTimeout("myclock();",500); } function flagss() { if(flag==0) flag=1; else flag=0; } ... Текущее время:
    Листинг 14.6.
    Закрыть окно

    var idp1 = null; function start() { d = new Date(); window.document.c1.f1.value = d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(); idp1=setTimeout("start();",500); } function stop() { clearTimeout(idp1);idp1=null; } ...
    Текущее время:
    Листинг 14.7.
    Закрыть окно

    function load() { if(self.document.f.s.options[document.f.s.selectedIndex].text=="top") { document.f.target = "mytop"; self.top.frames[2].document.open(); self.top.frames[2].document.close(); } else { document.f.target = "mybottom"; self.top.frames[1].document.open(); self.top.frames[1].document.close(); } return true; }
    Листинг 14.8.
    Закрыть окно

    function load() { if(self.document.f.s.options[document.f.s.selectedIndex].text=="top") { window.open("./framer.htm","mytop"); self.top.frames[2].document.open(); self.top.frames[2].document.close(); } else { window.open("./framer.htm","mybottom"); self.top.frames[1].document.open(); self.top.frames[1].document.close(); } return false; }
    Листинг 14.9.
    Закрыть окно

    Программируем defaultStatus

    Свойство defaultStatus определяет текст, отображаемый в поле статуса, когда никаких событий не происходит. В нашем документе мы определили его при загрузке документа:

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

    Программируем status

    Свойство status связано с отображением сообщений о событиях, отличных от простой загрузки страницы. Например, когда курсор мыши проходит над гипертекстовой ссылкой, URL, указанный в атрибуте HREF, отображается в поле статуса. При попадании курсора мыши на поле, свободное от ссылок, в поле статуса восстанавливается сообщение по умолчанию (Document:Done). Эта техника реализована на данной странице при переходе на описание свойств status и defaultStatus
    window.status
    В документации по JavaScript указано, что обработчик событий mouseover и mouseout должен возвращать значение true. Это нужно для того, чтобы браузер не выполнял действий, заданных по умолчанию. Практика показывает, что Netscape Navigator 4.0 прекрасно обходится и без возврата значения true.

    что браузер отображает страницу, расположенную

    Предположим, что браузер отображает страницу, расположенную по адресу:
    http://intuit.ru:80/r/dir/page?search#mark
    Тогда свойства объекта Location примут следующие значения:
    window.location.href = http://intuit.ru:80/r/dir/page?search#mark window.location.protocol = http; window.location.hostname = intuit.ru; window.location.host = intuit.ru:80; window.location.port = 80 window.location.pathname = /r/dir/; window.location.search = search; window.location.hash = mark;

    Тип браузера (объект Navigator)

    В связи с войной браузеров (которая, можно считать, уже закончилась в пользу Microsoft Internet Explorer) стала актуальной задача настройки страницы на конкретную программу просмотра. При этом возможны два варианта: определение типа браузера на стороне сервера и определение типа браузера на стороне клиента. Для последнего варианта в арсенале объектов JavaScript существует объект Navigator. Этот объект — свойство объекта Window.
    Рассмотрим простой пример определения типа программы просмотра:

    При нажатии на кнопку отображается окно предупреждения. В нем содержится строка userAgent, которую браузер помещает в соответствующий HTTP-заголовок.
    Эту строку можно разобрать по компонентам, например:
    Листинг 14.1.
    (html, txt)
    У объекта Navigator есть еще несколько интересных с точки зрения программирования применений. Например, проверка поддержки Java.
    Проиллюстрируем эту возможность на примере:
    Листинг 14.2.
    (html, txt)
    Аналогично можно проверить форматы графических файлов, которые поддерживает ваш браузер:
    Листинг 14.3.
    (html, txt)
    К сожалению, такая проверка не позволяет определить наличие автоматической подгрузки графики.
    on_load_lecture()
    Тип браузера (объект Navigator) Тип браузера (объект Navigator) Дальше "
    Тип браузера (объект Navigator) Если Вы заметили ошибку - сообщите нам. Тип браузера (объект Navigator) Страницы:
    1
    |
    2
    |
    3
    |
    вопросы | "
    |
    учебники
    |
    для печати и PDA
    Тип браузера (объект Navigator) Тип браузера (объект Navigator) Тип браузера (объект Navigator)
    Курсы | Учебные программы | Учебники | Новости | Форум | Помощь

    Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru

    © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование


    Управление окнами

    Что можно сделать с окном? Открыть (создать), закрыть (удалить), положить его поверх всех других открытых окон (передать фокус). Кроме того, можно управлять свойствами окна и свойствами подчиненных ему объектов. Описанию основных свойств посвящен раздел "Программируем свойства окна браузера", поэтому сосредоточимся на простых и наиболее популярных методах управления окнами:
  • alert();
  • confirm();
  • prompt();

  • open();

  • close();
  • focus();

  • setTimeout();
  • clearTimeout().

  • Здесь не указаны только два метода: scroll() и blur().
    Первый позволяет прокрутить окно на определенную позицию. Но его очень сложно использовать, не зная координат окна. Последнее является обычным делом, если только не используется технология программирования слоев или CSS (Cascading Style Sheets).
    Второй метод уводит фокус с окна. При этом совершенно непонятно, куда этот фокус будет передан. Лучше целенаправленно передать фокус, чем просто его потерять.

    Window.alert()

    Метод alert() позволяет выдать окно предупреждения:
    Повторите запрос!
    Все очень просто, но нужно иметь в виду, что сообщения выводятся системным шрифтом, следовательно, для получения предупреждений на русском языке нужна локализованная версия ОС.

    Window.clearTimeout

    Метод clearTimeout() позволяет уничтожить поток, вызванный методом setTimeout(). Очевидно, что его применение позволяет более эффективно распределять ресурсы вычислительной установки. Для того чтобы использовать этот метод в примере с часами, нам нужно модифицировать функции и форму:
    Листинг 14.7.
    (html, txt)
    В данном примере для остановки часов используется метод clearTimeout(). При этом, чтобы не порождалось множество потоков, проверяется значение указателя на объект потока.

    Window.close()

    Метод close() — это оборотная сторона медали метода open(). Он позволяет закрыть окно. Чаще всего возникает вопрос, какое из окон, собственно, следует закрыть. Если необходимо закрыть текущее, то:
    window.close(); self.close();
    Если необходимо закрыть родительское окно, т.е. окно, из которого было открыто текущее, то:
    window.opener.close();
    Если необходимо закрыть произвольное окно, то тогда сначала нужно получить его идентификатор:
    id=window.open(); ... id.close();
    Как видно из последнего примера, закрывают окно не по имени (значение атрибута TARGET тут ни при чем), а используют указатель на объект.

    Window.confirm()

    Метод confirm() позволяет задать пользователю вопрос, на который тот может ответить либо положительно, либо отрицательно:


    Все ограничения для сообщений на русском языке, которые были описаны для метода alert(), справедливы и для метода confirm().

    Window.focus()

    Метод focus() применяется для передачи фокуса в окно, с которым он использовался. Передача фокуса полезна как при открытии окна, так и при его закрытии, не говоря уже о случаях, когда нужно выбирать окна. Рассмотрим пример.
    Открываем окно и, не закрывая его, снова откроем окно с таким же именем, но с другим текстом. Новое окно не появилось поверх основного окна, так как фокус ему не был передан. Теперь повторим открытие окна, но уже с передачей фокуса:
    Листинг 14.5.
    (html, txt)
    Поскольку мы пишем содержание нового окна из окна старого (родителя), то в качестве указателя на объект используем значение переменной id.

    Window.open()

    У этого метода окна атрибутов больше, чем у некоторых объектов. Метод open() предназначен для создания новых окон. В общем случае его синтаксис выглядит следующим образом:
    open("URL","window_name","param,param,...", replace);
    где: URL — страница, которая будет загружена в новое окно, window_name — имя окна, которое можно использовать в атрибуте TARGET в контейнерах A и FORM.

    Таблица 2. ПараметрыНазначение
    replaceПозволяет при открытии окна управлять записью в массив History
    paramСписок параметров
    widthШирина окна в пикселах
    heightВысота окна в пикселах
    toolbarСоздает окно с системными кнопками браузера
    locationСоздает окно с полем location
    directoriesСоздает окно с меню предпочтений пользователя
    statusСоздает окно с полем статуса status
    menubarСоздает окно с меню
    scrollbarsСоздает окно с полосами прокрутки
    resizableСоздает окно, размер которого можно будет изменять

    Приведем следующий пример:
    Листинг 14.4.
    (html, txt)
    При нажатии кнопки "простое окно" получаем окно со следующими параметрами:
  • directories=no - окно без меню
  • height=200 - высота 200 px
  • location=no - поле location отсутствует
  • menubar=no - без меню
  • resizable=no - размер изменять нельзя
  • scrollbars=no - полосы прокрутки отсутствуют
  • status=no - статусная строка отсутствует
  • toolbar=no - системные кнопки браузера отсутствуют
  • width=200 - ширина 200

  • При нажатии кнопки "сложное окно" получаем окно, где:
  • directories=yes - окно с меню
  • height=200 - высота 200 px
  • location=yes - поле location есть
  • menubar=yes - меню есть
  • resizable=yes - размер изменять можно
  • scrollbars=yes - есть полосы прокрутки
  • status=yes - статусная строка есть
  • toolbar=yes - системные кнопки браузера есть
  • width=200 - ширина 200


  • Window.prompt()

    Метод prompt() позволяет принять от пользователя короткую строку текста, которая набирается в поле ввода информационного окна:

    Введенную пользователем строчку можно присвоить любой переменной и потом разбирать ее в JavaScript-программе.

    Window.setTimeout()

    Метод setTimeout() используется для создания нового потока вычислений, исполнение которого откладывается на время (ms), указанное вторым аргументом:
    idt = setTimeout("JavaScript_код",Time);
    Типичное применение этой функции — организация автоматического изменения свойств объектов. Например, можно запустить часы в поле формы:
    Листинг 14.6.
    (html, txt)
    Нужно иметь в виду, что поток порождается всегда, даже в том случае, когда часы стоят. Если бы он создавался только при значении переменной flag равном единице, то при значении 0 он исчез бы, тогда при нажатии на кнопку часы продолжали бы стоять.

    Введение в JavaScript

    Action

    Свойство action отвечает за вызов скрипта (CGI-скрипта). В нем указывается его (скрипта) URL. Но там, где можно указать URL, можно указать и его схему javascript:

    Обратите внимание на тот факт, что в контейнере FORM указан атрибут METHOD. В данном случае это сделано для того, чтобы к URL, заданному в action, не дописывался символ "?". Дело в том, что методом доступа по умолчанию является метод GET. В этом методе при обращении к ресурсу из формы создается элемент URL под названием search. Этот элемент предваряется символом "?", который дописывается к URL скрипта, а в нашем случае, к JavaScript-коду.
    Конструкция вида
    window.alert("String");void(0);?
    провоцирует ошибку JavaScript.
    Метод POST передает данные формы скрипту в теле HTTP-сообщения, поэтому символ "?" не добавляется к URL, и ошибка не генерируется. При этом применение void(0) отменяет перезагрузку документа, и браузер не генерирует событие submit, т.е. не обращается к серверу при нажатии на кнопку, как при стандартной обработке форм.

    Cookies

    Волшебные ключики, или cookies, не являются полями формы, но, тем не менее, отойдя от строгого рассмотрения иерархии объектов JavaScript, мы уделим им немного внимания, как одному из механизмов управления обменом данных. Основная функция cookie — поддержка сеанса работы между клиентом (браузером) и сервером.
    cookie — это небольшой фрагмент текста, который передается от сервера браузеру и потом может быть возвращен обратно. Подробно о cookie рассказано в "Спецификации Cookie", которую можно найти в главе "Дополнения". Программа на JavaScript способна прочитать выставленное значение cookie и даже изменить его. Для этой цели используют свойство объекта DOCUMENT — cookie:

    В данном случае cookies отображаются в виде одной большой строки со множеством значений. Свойство cookie документа можно переопределить:
    function asign() { document.cookie="n1=3"; window.alert(document.cookie); } ...

    Как видно из примера, программисту не нужно выделять cookie из строки. Браузер рассматривает cookies как ассоциированный массив (хеш) и изменяет значение cookie по имени "ключика".
    Наконец, cookie можно удалить. Если быть более точным — деактивировать, указав время его действия:
    function change_cookies() { a = new Array(); c = new Date(); a = document.cookie.split(';'); document.cookie=a[0]+"; expires="+c.toGMTString()+";"; window.alert(document.cookie); } ...

    В данном случае мы "удаляем" cookie за счет параметра expire (времени, до которого cookie живет). Так как мы берем текущее время, то cookie исчезает из списка "ключиков". Многократно нажимая на кнопку, можно удалить все cookies для данной страницы.

    Единственное поле в форме

    Если в форме присутствует одно-единственное поле, и мы в него осуществили ввод и после этого нажали Enter, то браузер сгенерирует событие submit:

    Перехватить такое событие и обработать можно только за счет программы обработки события submit в контейнере FORM, что и сделано в примере.
    В этом примере, кроме поля ввода, в форме присутствует меню. Если менять значения выбранных альтернатив, то перезагрузки не происходит, но стоит изменить значение в поле ввода и нажать Enter, происходит submit, и система выдает окно предупреждения.

    Elements[]

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

    Как видно из этого примера, индексирование полей в массиве начинается с цифры "0". Общее число полей в форме доступно как результат обращения
    document.forms[i].elements.length.

    Encoding

    Такое свойство у объекта Form есть, но не совсем понятно, как его использовать. Изменение свойства encoding оправдано только в том случае, когда в форме имеется поле типа file. В этом случае предполагается, что пользователю разрешена передача файла со своего локального диска на сервер. При этом если не указана кодировка multipart/form-data, то передаваться будет только имя файла, а если она указана, то и сам файл тоже.
    Первое, что приходит в голову по этому поводу, — отмена передачи файла при определенном стечении обстоятельств. Сам скрипт нужно размещать во внешнем файле, чтобы пользователь не изменил его код.

    Изменение значения поля ввода

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

    Если установить фокус на поле ввода и нажать Enter, ничего не произойдет. Если ввести что-либо в расположенное выше поле ввода, а потом нажать на Enter, то появится окно предупреждения с введенным текстом (для Netscape Navigator) или ничего не произойдет (для Internet Explorer последних версий). Если вы используете Internet Explorer последних версий, то окно предупреждения появится только после установки фокуса вне поля ввода. Это следует прокомментировать следующим образом: во-первых, обработчик onChange вызывается только тогда, когда ввод в поле закончен. Событие не вызывается при каждом нажатии на кнопки клавиатуры при вводе текста в поле. Во-вторых, обработчик события не вызывается при изменении значения атрибута VALUE из JavaScript-программы. В этом можно убедиться, нажав на кнопку Change - окно предупреждения не открывается. Но если ввести что-то в поле, а после этого нажать на Change, окно появится.
    Отметим, что он работает по-разному для Internet Explorer и Netscape Navigator, а именно по-разному обрабатывается событие onChange. Для Internet Explorer при любом изменении поля событие обрабатывается незамедлительно, для Netscape Navigator — после потери фокуса активным полем.

    Картинки

    Кнопки-картинки — это те же кнопки, но только с возможностью отправки данных на сервер. Собственно, такие кнопки в JavaScript составляют две разновидности контейнера INPUT: image и submit. В JavaScript объект, связанный с данными кнопками, называется Submit.
    Активная кнопка:

    Как мы уже отмечали, данный объект обладает теми же свойствами, методами и событиями, что и объект Button. Но вот реакция в разных браузерах при обработке событий может быть различной. Так, в событии onClick в Internet Explorer можно отменить передачу данных на сервер, выдав в качестве значения возврата false. Netscape Navigator на такое поведение обработчика события вообще не реагирует, и отменять передачу можно только в атрибуте onSubmit контейнера FORM:
    Активная кнопка:

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

    Кнопка Submit

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

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

    Из этого примера видно, что кнопка Submit ведет себя несколько иначе, чем графическая кнопка в Netscape Navigator, но так же, как графическая кнопка в Internet Explorer (со временем различия наверняка исчезнут). При нажатии на кнопку перезагрузки страницы не происходит — передача данных на сервер отменена. Обработчик действует так же, как обработчик события submit в контейнере FORM.
    Теперь можно написать собственную программу обработки события submit:
    function my_submit() { if(window.confirm("Хотите перегрузить страницу?")) return true; else return false; } ...

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

    Кнопки

    Использование кнопок в Web вообще немыслимо без применения JavaScript. Создайте форму с кнопкой и посмотрите, что будет, если на эту кнопку нажать — кнопка продавливается, но ничего не происходит. Ни одно из стандартных событий формы (reset или submit) не вызывается. Конечно, данное замечание не касается кнопок Submit и Reset.
    Кнопка вводится в форму главным образом для того, чтобы можно было обработать событие click:

    Текст, отображаемый на кнопке, определяется атрибутом VALUE контейнера INPUT. С этим атрибутом связано свойство value объекта Button. Любопытно, что, согласно спецификации, изменять значение данного атрибута нельзя. Однако в версии 4 Netscape Navigator и Internet Explorer это допустимо.
    Следует отметить, что в Netscape Navigator размер кнопки фиксирован (первое значение должно быть самым длинным, иначе будет не очень красиво), а в Internet Explorer размер изменяется в зависимости от длины текста.

    Контейнер FORM

    Если рассматривать программирование на JavaScript в исторической перспективе, то первыми объектами, для которых были разработаны методы и свойства, стали поля форм. Обычно контейнер FORM и поля форм именованы:

    Поэтому в программах на JavaScript к ним обращаются по имени:
    window.document.f_name.i_name.value="Текстовое поле";
    Того же эффекта можно достичь, используя массив форм загруженного документа:
    window.document.forms[0].elements[0].value="Текстовое поле";
    В данном примере не только к форме, но и к полю формы мы обращаемся как к элементу массива.
    Рассмотрим подробнее объект Form, который соответствует контейнеру FORM.
    СвойстваМетодыСобытия

  • action
  • method
  • target
  • elements[]
  • encoding


  • reset()
  • submit()


  • onReset
  • onSubmit


  • Сами по себе методы, свойства и события объекта Form используются нечасто. Их переопределение обычно связано с реакцией на изменения значений полей формы.

    Length

    В примерах перепрограммирования options[] активно используется свойство объекта Select length. Оно определяет количество альтернатив, заданных для поля выбора. При помощи этого свойства можно удалять и восстанавливать списки.
    Определим посредством этого свойства число вариантов в предыдущем примере:
    Число вариантов:

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

    Method

    Свойство method определяет метод доступа к ресурсам HTTP-сервера из программы-браузера. В зависимости от того, как автор HTML-страницы собирается получать и обрабатывать данные из формы, он может выбрать тот или иной метод доступа. На практике чаще всего используются методы GET и POST.
    JavaScript-программа может изменить значение этого свойства. В предыдущем разделе (action) метод доступа в форме был указан явно. Теперь мы его переопределим в момент исполнения программы:
    Пример 15.1.
    (html, txt)
    По умолчанию установлен метод GET.
    В данном примере стоит обратить внимание на два момента:
  • Прежде чем открывать окно предупреждения, следует нажать кнопку "Метод POST". Если этого не сделать, то появится сообщение об ошибке JavaScript. Здесь все выглядит достаточно логично. Формирование URL происходит при генерации события submit, а вызов скрипта — после того, как событие сгенерировано. Поэтому вставить переопределение метода в обработчик события нельзя, так как к этому моменту будет уже сгенерирован URL, который, в свою очередь, будет JavaScript-программой с символом "?" на конце. Переопределение метода должно быть выполнено раньше, чем произойдет событие submit.
  • В тело документа через контейнер SCRIPT встроен JavaScript-код, который сообщает метод доступа, установленный в форме по умолчанию. Этот контейнер расположен сразу за контейнером FORM. Ставить его перед контейнером FORM нельзя, так как в момент получения интерпретатором управления объект FORM не будет создан, и, следовательно, работать с его свойствами не представляется возможным.

  • Никаких других особенностей свойство method не имеет. В данном свойстве можно указать и другие методы доступа, отличные от GET и POST, но это требует дополнительной настройки сервера.

    Метод submit()

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

    При выборе альтернативы пользователь сразу инициирует обмен данными с сервером. Событие submit в данном случае обработчиком событий не перехватывается, в отличие от нажатия Enter. Такое поведение браузера довольно логично. Если программист вызвал метод submit(), то, наверное, он предварительно проверил данные, которые отправляет на сервер.

    Объект Option

    Объект Option интересен тем, что в отличие от многих других объектов JavaScript, имеет конструктор. Это означает, что программист может сам создать объект Option:
    opt = new Option([ text, [ value, [ defaultSelected, [ selected ] ] ] ]);
    где:
    text — строка текста, которая размещается в контейнере
  • (
  • текст);
  • value — значение, которое передается серверу при выборе альтернативы, связанной с объектом Option;
    defaultSelected — альтернатива выбрана по умолчанию(true/false);
    selected — альтернатива выбрана(true/false).

    На первый взгляд не очень понятно, для чего может понадобиться программисту такой объект, ведь создать объект типа Select нельзя и, следовательно, нельзя приписать ему новый объект OPTION. Все объясняется, когда речь заходит об изменении списка альтернатив встроенных в документ объектов Select. Делать это можно, так как изменение списка альтернатив Select не приводит к переформатированию документа. Изменение списка альтернатив позволяет решить проблему создания вложенных меню, которых нет в HTML-формах, путем программирования обычных меню (options[]).
    При программировании альтернатив (объект Option) следует обратить внимание на то, что среди свойств Option нет свойства name. Это означает, что к объекту нельзя обратиться по имени. Отсутствие свойства объясняется тем, что у контейнера OPTION нет атрибута NAME. К встроенным в документ объектам Option можно обращаться только как к элементам массива options[] объекта Select.

    Обмен данными

    Передача данных на сервер из формы осуществляется по событию submit. Это событие происходит при одном из следующих действий пользователя:
  • нажата кнопка Submit;
  • нажата графическая кнопка;
  • нажата клавиша Enter в форме из одного поля;
  • вызван метод submit().

  • При описании отображения контейнера FORM на объекты JavaScript было подробно рассказано об обработке события submit. В данном разделе мы сосредоточимся на сочетании JavaScript-программ в атрибутах полей и обработчиках событий. Особое внимание нужно уделить возможности перехвата/генерации события submit.

    OnChange

    Событие change наступает в тот момент, когда изменяется значение выбранного индекса в объекте Select. С изменением этого индекса в полях выбора единственного варианта на данной странице мы сталкивались неоднократно (selectedIndex и options[]). Данное событие обрабатывается JavaScript-программой, которая указывается в атрибуте onChange контейнера SELECT. В этом контексте интересно посмотреть, что происходит, когда мы имеем дело с multiple контейнером SELECT:
    Набор канцелярских товаров: Выбраны позиции:

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

    OnReset

    Событие reset (восстановление значений по умолчанию в полях формы) возникает при нажатии на кнопку типа Reset или при выполнении метода reset(). В контейнере FORM можно переопределить функцию обработки данного события. Для этой цели в него введен атрибут onReset:

    В этом примере следует обратить внимание на то, что обработчик события reset возвращает логическое значение false. Это сделано для того, чтобы перехватить обработку события reset полностью. Если обработчик события возвращает значение false, то установка полей по умолчанию не производится; если обработчик событий возвращает значение true, то установка значений полей по умолчанию производится.

    OnSubmit

    Событие submit возникает при нажатии на кнопку типа Submit, графическую кнопку (тип image) или при вызове метода submit(). Для переопределения метода обработки события submit в контейнер FORM добавлен атрибут onSubmit. Функция, определенная в этом атрибуте, будет выполняться перед тем, как отправить данные на сервер. При этом в зависимости от того, что функция вернет в качестве значения, данные либо будут отправлены, либо нет.
    Пример 15.3.
    (html, txt)
    В этом примере следует обратить внимание на конструкцию return test();. Сама функция test() возвращает значения true или false. Соответственно, данные либо отправляются на сервер, либо нет.
    on_load_lecture()
    OnSubmit OnSubmit Дальше "
    OnSubmit Если Вы заметили ошибку - сообщите нам. OnSubmit Страницы:
    1
    |
    2
    |
    3
    |
    вопросы | "
    |
    учебники
    |
    для печати и PDA
    OnSubmit OnSubmit OnSubmit
    Курсы | Учебные программы | Учебники | Новости | Форум | Помощь

    Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru

    © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование


    Options[]

    Массив options[] — это свойство объекта Select. Элементы этого массива обладают теми же свойствами, что и объекты Option. Собственно, это и есть объекты Option, встроенные в документ. Они создаются по мере загрузки страницы браузером. Программист имеет возможность не только создавать новые объекты Option, но и удалять уже созданные браузером объекты:

    В данном примере при загрузке страницы с сервера определено три альтернативы. Они появляются, если выбрать поле select. После нажатия на кнопку удаления последнего варианта ("Delete last option") остается только две альтернативы. Если еще раз нажать на кнопку удаления альтернативы, останется только одна альтернатива и т.д. В конечном счете, вариантов может не остаться вообще, т.е. пользователь лишится возможности выбора. Кнопка Reset показывает, что альтернативы утеряны бесследно, так как после нажатия на эту кнопку содержание поля SELECT не восстанавливается.
    Теперь, используя конструктор Option, сделаем процесс обратимым:
    function def_f1() { document.f1.s1.options[0] = new Option("вариант Один","",true,true); document.f1.s1.options[1] = new Option("вариант Два"); document.f1.s1.options[2] = new Option("вариант Три"); return false; } ...

    В данном случае мы обрабатываем событие reset (контейнер FORM). При этом создаем новые объекты типа Option и подчиняем их объекту Select. При этом первый элемент массива должен быть выбран по умолчанию, чтобы смоделировать поведение при начальной загрузке страницы.
    В HTML-формах нельзя реализовать подменю. JavaScript позволяет обойти это ограничение и выполнить замену путем программирования поля select.

    в качестве an

    Пример 15.1.
    Закрыть окно

    for(i=1;iВыбрали этот фрейм"); id.frames[i].document.close(); } else {id.frames[i].document.open(); id.frames[i].document.write("
    Этот фрейм не выбрали
    "); id.frames[i].document.close(); } }
    Пример 15.2.
    Закрыть окно

    function test() { if(parseInt(document.sub.digit.value).toString()=="NaN") { window.alert(" Некорректные данные в поле формы."); return false; } else { return true; } } ...
    Пример 15.3.
    Закрыть окно

    Число гипертекстовых ссылок: до момента обработки формы.
    Пример 15.4.
    Закрыть окно

    Reset()

    Метод reset(), не путать с обработчиком события onReset, позволяет установить значения полей формы по умолчанию. При этом использовать кнопку типа Reset не требуется:
    Установили значение по умолчанию
    В данном примере по гипертекстовой ссылке происходит возврат в форме значения по умолчанию.

    Selected

    Свойство selected объекта Option, на котором был построен пример с канцелярскими принадлежностями, может принимать два значения: истина (true) или ложь (false). В примере мы распечатываем индекс выбранной альтернативы, если значение свойства selected у объекта Option — true:
    if(form.elements[0].options[i].selected==true) ...
    Вообще говоря, свойство selected интересно именно в случае поля множественного выбора. В случае выбора единственного варианта его можно получить, указав на свойство selectedIndex объекта Select.

    SelectedIndex

    Свойство объекта Select, которое возвращает значение выбранного варианта, обозначается как selectedIndex.
    Вариант: Выбрали индекс:

    В этом примере обратите внимание на обработчики событий. Сам обработчик onChange мы опишем позже. Главное сейчас не это. Посмотрите, как мы обращаемся к элементам текущей формы. Во-первых, мы используем имя form. Оно указывает на объект Form, к которому принадлежит поле. Во-вторых, мы ссылаемся на второй элемент формы. На данный момент он не определен, но событие произойдет только тогда, когда мы будем выбирать вариант. К этому моменту поле уже будет определено. В-третьих, мы ссылаемся на selectedIndex, не указывая полного имени формы. В данном контексте он относится к текущей форме.

    Списки и выпадающие меню

    В данном случае речь пойдет о выпадающих меню в контексте форм, а не в контексте слоев и технологии CSS.
    Одним из важных элементов интерфейса пользователя является меню. В HTML-формах для реализации меню используются поля типа select (контейнер SELECT, который, в свою очередь, вмещают в себя контейнеры OPTION). Эти поля представляют собой списки вариантов выбора. При этом список может "выпадать" или прокручиваться внутри окна. Поля типа select позволяют выбрать из списка только один вариант, либо отметить несколько вариантов. Для управления полями типа select в JavaScript существуют объекты Select и Option.
    Эти объекты характеризуются следующими свойствами, методами и событиями:
    Объект SelectСвойстваМетодыСобытия

  • form
  • length
  • name
  • options[]
  • selectedIndex
  • type


  • blur()
  • click()
  • focus()


  • onBlur
  • onChange
  • onFocus

  • Объект OptionСвойстваМетодыСобытия

  • defaultSelected
  • index
  • selected
  • text
  • selectedIndex
  • value

  • нетнет

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

    Submit()

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

    Target

    Свойство target определяет имя окна, в которое следует загружать результат обращения к CGI-скрипту. Применение значения этого свойства внутри JavaScript-программ не оправдано, так как всегда можно получить идентификатор окна или задействовать встроенный массив frames[0] и свойства окна opener, top, parent и т.п. Для загрузки внешнего файла в некоторое окно всегда можно применить метод window.open(). Но тем не менее использовать это свойство можно:
    Пример 15.2.
    (html, txt)
    В примере организован цикл перебора имен фреймов. Если имя совпадает с указанным именем, то фрейм считается выбранным. Здесь нужно сделать следующее замечание: при работе с Internet Explorer обращения к фреймам по индексу следует избегать.

    Текст в полях ввода

    Поля ввода (контейнер INPUT типа TEXT) являются одним из наиболее популярных объектов программирования на JavaScript. Это объясняется тем, что, помимо использования по прямому назначению, их применяют и в целях отладки программ, вводя в эти поля промежуточные значения переменных и свойств объектов.
    Пример 15.4.
    (html, txt)
    В данном примере первое поле формы — это поле ввода. Используя подстановку, мы присваиваем ему значение по умолчанию, а потом при помощи кнопки изменяем это значение.
    Объект Text (текстовое поле ввода) характеризуется следующими свойствами, методами и событиями:
    СвойстваМетодыСобытия

  • defaultValue
  • form
  • name
  • type
  • value


  • blur()
  • focus()
  • select()


  • onBlur
  • onChange
  • onFocus


  • Свойства объекта Text — это стандартный набор свойств поля формы. В полях ввода можно изменять только значение свойства value.
    Обычно при программировании полей ввода решают две типовых задачи: защита поля от ввода данных пользователем и реакция на изменение значения поля ввода.

    Text

    Свойство text представляет собой отображаемый в меню текст, который соответствует альтернативе:

    В данном примере свойство text выводится в текстовое поле формы.

    Value

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

    Защита поля ввода

    Для защиты поля от ввода в него символов применяют метод blur() в сочетании с обработчиком события onFocus:

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

    Введение в JavaScript

    Графика и обработка событий

    В данном разделе мы не будем рассматривать обработчики событий контейнера IMG. Мы остановимся на наиболее типичном способе комбинирования обработчиков событий и изменения графических образов. Собственно, не имело бы смысла применять нарезанную графику, если бы не возможность использования обработчиков событий для изменения отдельных частей изображения. Продолжая обсуждение примера с навигационным деревом, покажем его развитие с обработкой событий, вызванных наведением мыши на объект, и изменением картинок:
    Пример 16.3.
    (html, txt)
    В данном примере при проходе курсор мышки через картинки меню последние изменяются. Этот эффект достигается за счет применения двух событий: onMouseover и onMouseout. По первому событию картинка меняется с позитива на негатив, по второму событию восстанавливается первоначальный вариант. Следует заметить, что события определены в контейнере якоря (A), а не в контейнере IMG. Это наиболее устойчивый с точки зрения совместимости браузеров вариант.
    on_load_lecture()
    Графика и обработка событий Графика и обработка событий Дальше "
    Графика и обработка событий Если Вы заметили ошибку - сообщите нам. Графика и обработка событий Страницы:
    " |
    1
    |
    2
    |
    3
    |
    4
    |
    вопросы | "
    |
    учебники
    |
    для печати и PDA
    Графика и обработка событий Графика и обработка событий Графика и обработка событий
    Курсы | Учебные программы | Учебники | Новости | Форум | Помощь

    Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru

    © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование


    Графика и таблицы

    Одним из наиболее популярных приемов дизайна страниц Web-узла является техника нарезки картинок на составные части. Можно выделить следующие способы применения этой техники для организации навигационных компонентов страницы:
  • горизонтальные и вертикальные меню;
  • вложенные меню;
  • навигационные графические блоки.

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

    Графика и таблицы
    Рис. 16.1. 
    Элементы переносятся на новую строку, так как ширина раздела меньше общей ширины всех картинок. Проблема решается, если применить защиту от парсера —
    : (открыть) 
      

    Графика и таблицы
    Рис. 16.2. 
    Использование такого меню требует определения на нем гипертекстовых ссылок, что приводит к следующему эффекту: (открыть)
      

    Графика и таблицы
    Рис. 16.3. 
    Этого можно достичь за счет применения атрибута BORDER равного 0: (открыть)
      


    Графика и таблицы
    Рис. 16.4. 

    Теперь попробуем тем же способом реализовать многострочное меню: (открыть)

    Пример 16.1.

    (html, txt)

    Графика и таблицы
    Рис. 16.5. 

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

    Пример 16.2.

    (html, txt)

    Графика и таблицы
    Рис. 16.6. 

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

    Изменение картинки

    Изменить картинку можно, только присвоив свойству src встроенного объекта Image новое значение. На странице "Программирование графики" показано, как это делается в простейшем случае. Очевидно, что медленная перезагрузка картинки с сервера не позволяет реализовать быстрое листание. Попробуем решить эту проблему.
    Собственно, решение заключается в разведении по времени подкачки картинки и ее отображения. Для этой цели используют конструктор объекта Image:
    ...

    Фрагмент кода показывает типовой прием замещения и восстановления картинки при проходе курсора мыши. Естественно, что менять можно не одну, а сразу несколько картинок.
    Главное, тем не менее, не в том, что картинки замещаются, а в том, с какой скоростью они это делают. Для достижения нужного результата в начале страницы создаются массивы картинок, в которые перед отображением перекачивается графика (обратите внимание на строку статуса при загрузке страницы):
    color = new Array(32); mono = new Array(32); for(i=0;i<32;i++) { mono[i] = new Image(); color[i] = new Image(); if(i.toString().length==2) { mono[i].src = "images0"+i+".gif"; color[i].src = "images0"+i+".gif"; } else { mono[i].src = "images00"+i+".gif"; color[i].src = "images00"+i+".gif"; } }
    Еще один характерный прием — применение функции отложенного исполнения JavaScript-кода (eval()):
    function def() { for(i=0;i<32;i++) { eval("document.m"+i+".src=mono["+i+"].src"); } for(i=0;i<5;i++) { eval("document.r"+i+".src=rm["+i+"].src"); } }
    В данном случае eval() избавляет нас от необходимости набирать операции присваивания (32 строки — это не фунт изюму).

    Мультипликация

    Естественным продолжением идеи замещения значения атрибута SRC в контейнере IMG является мультипликация, т.е. последовательное изменение значения этого атрибута во времени. Для реализации мультипликации используют метод объекта Window — setTimeout().
    Собственно, существует два способа запуска мультипликации:
  • onLoad();
  • onClick(), onChange() ...

  • Наиболее популярный — setTimeout() при onLoad().

    Нарезка картинок

    Нарезка картинок применяется довольно часто. Она позволяет достигать эффекта частичного изменения отображаемой картинки. Чаще всего он применяется при создании меню.
    Кроме подобного эффекта нарезка позволяет реализовать мультипликацию на больших картинках. При этом изменяется не весь образ, а только отдельные его части.
    on_load_lecture()
    Нарезка картинок Нарезка картинок Дальше "
    Нарезка картинок Если Вы заметили ошибку - сообщите нам. Нарезка картинок Страницы:
    " |
    1
    |
    2
    |
    3
    |
    4
    |
    вопросы | "
    |
    учебники
    |
    для печати и PDA
    Нарезка картинок Нарезка картинок Нарезка картинок
    Курсы | Учебные программы | Учебники | Новости | Форум | Помощь

    Телефон: +7 (495) 253-9312, 253-9313, факс: +7 (495) 253-9310, email: info@intuit.ru

    © 2003-2007, INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование


    Объект Image

    Наиболее зрелищные эффекты при программировании на JavaScript достигаются при работе с графикой. При этом в арсенале программиста не так уж много инструментов: встроенные в документ картинки, возможность генерации объекта Image, комбинирование картинок с гипертекстовыми ссылками и таблицами. Тем не менее обилие различных эффектов, которые достигаются этими нехитрыми средствами, впечатляет.
    Программирование графики в JavaScript опирается на объект Image, который характеризуется следующими свойствами, методами и событиями:
    СвойстваМетодыСобытия

  • border
  • complete
  • height
  • hspace
  • name
  • src
  • vspace
  • width
  • lowsrc

  • нет
  • onAbort
  • onError
  • onLoad


  • Несмотря на такое обилие свойств, их абсолютное большинство можно только читать, но не изменять. Об этом свидетельствует, прежде всего, отсутствие методов. Но два свойства все же можно изменять: src и lowsrc. Этого оказывается достаточно для множества эффектов с картинками.
    Все объекты класса Image можно разделить на встроенные и порожденные программистом. Встроенные объекты — это картинки контейнеров IMG. Если эти картинки поименовать, к ним можно обращаться по имени:

    Картинка активна. Если на нее нажать, получим имя контейнера IMG. Обращение document.images[0].name позволяет распечатать это имя в окне предупреждения. При этом само имя указано как name=intuit в контейнере IMG.
    К встроенному графическому объекту можно обратиться и по индексу:
    document.images[0];
    В данном случае images[0] — это первая картинка документа.

    Оптимизация отображения

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

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

    Оптимизация при загрузке

    Практически в любом руководстве по разработке HTML-страниц отмечается, что при использовании контейнера IMG в теле HTML-страницы следует указывать атрибуты WIDTH и HEIGHT. Это продиктовано порядком загрузки компонентов страницы с сервера и алгоритмом работы HTML-парсера. Первым загружается текст разметки. После этого парсер разбирает текст и начинает загрузку дополнительных компонентов, в том числе графики. При этом загрузка картинок, в зависимости от типа HTTP-протокола, может идти последовательно или параллельно.
    Также параллельно с загрузкой парсер продолжает свою работу. Если для картинок заданы параметры ширины и высоты, то можно отформатировать текст и отобразить его в окне браузера. До тех пор, пока эти параметры не определены, отображения текста не происходит.
    Таким образом указание высоты и ширины картинки позволит отобразить документ раньше, чем картинки будут получены с сервера. Это дает пользователю возможность читать документ или задействовать его гипертекстовые ссылки до момента полной загрузки (событие load).
    С точки зрения JavaScript, указание размеров картинки задает начальные параметры окна отображения графики внутри документа. Это позволяет воспользоваться маленьким прозрачным образом, для того, чтобы заменить его полноценной картинкой. Идея состоит в передаче маленького объекта для замещения его по требованию большим объектом.

    Предварительная загрузка

    Замена одного образа другим часто бывает оправдана только в том случае, когда это происходит достаточно быстро. Если перезагрузка длится долго, то эффект теряется. Для быстрой подмены используют возможность предварительной загрузки документа в специально созданный объект класса Image.
    Реальный эффект можно почувствовать только при отключении кэширования страниц на стороне клиента (браузера). Кэширование часто используют для ускорения работы со страницами Web-узла. Как правило, загрузка первой страницы — это достаточно длительный процесс. Самое главное, чтобы пользователь в этот момент был готов немного подождать. Поэтому, кроме графики, необходимой только на первой странице, ему можно передать и графику, которая на ней не отображается. Но зато при переходе к другим страницам узла она будет отображаться без задержки на передачу с сервера.
    Описанный выше прием неоднозначен. Его оправдывает только то, что если пользователь нетерпелив, то он вообще отключит передачу графики.

    Пример IMG SRC=tree.gif

         
    Пример 16.1.
    Закрыть окно

    Пример 16.2.
    Закрыть окно

    Пример 16.3.
    Закрыть окно

    Пример 16.4.
    Закрыть окно

    Пример 16.5.
    Закрыть окно


    Пример 16.6.
    Закрыть окно

    Событие onLoad()

    Событие onLoad() наступает в момент окончания загрузки документа браузером. Обработчик события указывается в контейнере BODY:
    ... ...
    В нашем случае при загрузке документа должен начать выполняться цикл изменения картинки:
    function movie() { eval("document.images[0].src='clock"+ i+".gif';"); i++;if(i>6) i=0; setTimeout("movie();",500); } ... ...
    В примере используется бесконечный цикл, хотя можно реализовать и конечное число подмен:
    function movie() { eval("document.images[0].src='clock"+ i+".gif';"); i++; if(i<7) { setTimeout("movie();",500);} } ...
    В обоих примерах следует обратить внимание на использование метода setTimeout(). На первый взгляд, это просто рекурсия. Но в действительности все несколько сложнее. JavaScript разрабатывался для многопоточных операционных систем, поэтому правильнее будет представлять себе исполнение скриптов следующим образом:
  • Скрипт получает управление при событии onLoad().
  • Заменяет картинку.
  • Порождает новый скрипт и откладывает его исполнение на 500 миллисекунд.
  • Текущий скрипт уничтожается JavaScript-интерпретатором.

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

    Src и lowsrc

    Свойства src и lowsrc определяют URL изображения, которое монтируется внутрь документа. При этом lowsrc определяет временное изображение, обычно маленькое, которое отображается, пока загружается основное изображение, чей URL указывается в атрибуте SRC контейнера IMG. Свойство src принимает значение атрибута SRC контейнера IMG. Программист может изменять значения и src, и lowsrc. Рассмотрим пример с src:
    document.i2.src="images2.gif";
    Как видно из этого примера, существует возможность модифицировать вмонтированную картинку за счет изменения значения свойства src встроенного объекта Image. Если вы в первый раз просматриваете данную страницу (т.е. картинки не закешированы браузером), то постепенное изменение картинки будет заметно. Как ускорить это изменение, мы рассмотрим в следующем разделе.

    Вертикальные и горизонтальные меню

    Практически все, что изложено в разделах "Графика и таблицы" и "Графика и обработка событий" касается вопросов построения одноуровневых меню. Поэтому в данном разделе мы постараемся привести более или менее реальные примеры таких меню. Графическое меню удобно тем, что автор может всегда достаточно точно расположить его компоненты на экране. Это, в свою очередь, позволяет и другие элементы страницы точнее располагать относительно элементов меню: (открыть)
    Пример 16.4.
    (html, txt)
    Вертикальные и горизонтальные меню
    Рис. 16.7. 
    В данном случае стрелочка бежит точно над тем элементом, на который указывает мышь. По большому счету, применение атрибута ALT у IMG и его дублирование в строке статуса является гораздо более информативным, чем добавление нового графического элемента. Правда, отображается содержание ALT с некоторой задержкой: (открыть)
    Вертикальные и горизонтальные меню
    Рис. 16.8. 
    Посмотрим теперь на реализацию вертикального меню, построенного на основе графических блоков текста, как сейчас это принято делать: (открыть)
    Пример 16.5.
    (html, txt)
    Вертикальные и горизонтальные меню
    Рис. 16.9. 
    При движении мыши у соответствующего компонента, попавшего в фокус мыши, "отгибается уголок". В данном случае "уголок" — это самостоятельная картинка. Все уголки реализованы в правой колонке таблицы. Для того чтобы гипертекстовая ссылка срабатывала по обеим картинкам (тексту и "уголку"), применяются одинаковые контейнеры A, охватывающие графические образы. В этом решении есть один недостаток: при переходе от текста к "уголку" последний "подмигивает". Картинки можно разместить и в одной ячейке таблицы, но тогда нужно задать ее ширину, иначе при изменении размеров окна браузера картинки могут "съехать". Чтобы убрать "подмигивание", необходимо сделать полноценные картинки замены.
    "Подмигивание" происходит при переходе с одного элемента разметки контейнера на другой. При этом заново определяются свойства отображения элемента.

    Пример 16.4.

    Вертикальные и горизонтальные меню
    Рис. 16.7. 

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

    Вертикальные и горизонтальные меню
    Рис. 16.8. 

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




    Пример 16.5.

    Вертикальные и горизонтальные меню
    Рис. 16.9. 

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

    "Подмигивание" происходит при переходе с одного элемента разметки контейнера на другой. При этом заново определяются свойства отображения элемента.

    Вложенные меню

    При обсуждении программирования форм отмечено, что в HTML нет стандартного способа реализации вложенных меню. Тем не менее за счет графики можно создать их подобие. При этом следует понимать, что место, на которое ложится графика, нельзя заполнить текстом:
    Пример 16.6.
    (html, txt)
    Вложенные меню
    Рис. 16.10. 
    В этом примере вложенное меню расположено справа от основного. Эффект вложенности достигается за счет изменения цвета. Подчиненность меню можно подчеркнуть изменением его положения относительно основного меню: (открыть)
    Вложенные меню
    Рис. 16.11. 
    В этом случае для продвижения меню вниз необходимо зарезервировать место при помощи невидимых или видимых картинок. Это не обязательно должны быть иллюстративные картинки, которые не несут никакой нагрузки.
    При использовании слоев можно создать настоящее выпадающее меню.

    Запуск и остановка мультипликации

    Перманентная мультипликация может быть достигнута и другими средствами, например многокадровыми графическими файлами. Однако движение на странице — не всегда благо. Часто возникает желание реализовать запуск и остановить движения по требованию пользователя. Удовлетворим это желание, используя предыдущие примеры (запустить или остановить мультипликацию):
    var flag1=0; function movie() { if(flag1==0) { eval("document.images[0].src='clock"+ i+".gif';"); i++;if(i>6) i=0; } setTimeout("movie();",500); } ... ...

    В данном случае мы просто обходим изменение картинки, но при этом не прекращаем порождение потока. Если мы поместим setTimeout() внутрь конструкции if(), то после нажатия на кнопку Start/Stop поток порождаться не будет, и запустить движение будет нельзя.
    Существует еще один способ решения проблемы остановки и старта мультипликации. Он основан на применении метода clearTimeout(). Внешне все выглядит по-прежнему, но процесс идет совсем по-другому:
    var flag1=0; var id1; function movie() { eval("document.images[0].src='clock"+ i+".gif';"); i++;if(i>6) i=0; id1 = setTimeout("movie();",500); } ... ...

    Обратите внимание на два изменения. Во-первых, объявлен и используется идентификатор потока (id1); во-вторых, применяется метод clearTimeout(), которому, собственно, идентификатор потока и передается в качестве аргумента. Чтобы остановить воспроизведение функции movie() достаточно "убить" поток.

    Введение в JavaScript

    Изменение части URL

    Гипертекстовая ссылка — это объект класса URL. У этого объекта можно изменять и другие свойства. Проиллюстрируем эту возможность при частичном изменении ссылки. Распечатаем сначала свойство, которое не зависит от протокола (в нашем случае от javascript) document.all.next.pathname: href:--> http://intuit.ru/help/index.html
    pathname:--> help/index.html Изменим теперь pathname: document.all.next.pathname="test"; document.write( window.document.all.next.pathname); href:--> http://intuit.ru:80/test pathname--> test
    Обратите внимание, что Internet Explorer самостоятельно добавил в ссылку номер порта. По этой причине использовать свойства, отличные от href, в ссылках, где используется схема javascript, не рекомендуется.

    Массивы встроенных гипертекстовых ссылок

    К встроенным гипертекстовым ссылкам относятся собственно ссылки (...) и ссылки "чувствительных" графических картинок. Они составляют встроенный массив гипертекстовых ссылок документа (document.links[]).
    К сожалению, обратиться по имени к гипертекстовой ссылке нельзя. Точнее такое обращение не рекомендуется в силу различий между браузерами. Поэтому обращаться к ним можно только как к массиву встроенных ссылок. В качестве примера распечатаем гипертекстовые ссылки некоторого документа:
    for(i=0;i");
    Список ссылок:
    http://www.intuit.ru/help/index.html http://www.intuit.ru/help/terms.html http://www.intuit.ru/help/shop.html
    Вставим в документ контейнер MAP:

    И снова распечатаем массив ссылок:
    links[0]:http://www.intuit.ru/help/index.html links[1]:http://www.intuit.ru/help/terms.html links[2]:http://www.intuit.ru/help/shop.html links[3]:javascript:window.alert('Area_Link_1');void(0); links[4]:javascript:window.alert('Area_Link_2');void(0);
    Две новые ссылки — это ссылки из контейнера MAP, который не отображается, но ссылки из него попадают в массив встроенных ссылок. При этом, как в нашем случае, они могут попасть между обычными гипертекстовыми ссылками, если контейнер MAP расположить внутри текста документа. На данной странице он помещен перед контейнером SCRIPT, в котором мы распечатываем массив встроенных ссылок.

    Объект URL

    Объект класса URL обладает свойствами, которые определены схемой URL. В качестве примера рассмотрим ссылку на применение атрибута SRC в контейнере IMG:
    http://intuit.ru/help/index.html Значения свойств

    href:
    http://intuit.ru/help/index.html

    protocol:
    http:

    hostname:
    intuit.ru

    host:
    intuit.ru:80

    port:
    80

    pathname:
    help/index.html

    search:
     

    hash:
     

    Обращение к свойству объекта класса URL выглядит как:
    имя_объект_класса_URL.свойство
    Например, так:
    document.links[0].href document.location.host document.links[2].hash
    Свойства объекта URL дают программисту возможность менять только часть URL – объекта (гипертекстовой ссылки, например). Наиболее интересно это выглядит в объекте Location , когда при изменении свойства происходит перезагрузка документа. Однако и при работе с обычными гипертекстовыми ссылками такая технология более предпочтительна, чем изменение всего URL целиком.
    Здесь следует заметить, что чаще всего все-таки меняют весь URL. Это связано с тем, что такое действие более понятно с точки зрения HTML-разметки. Ведь у контейнера A нет атрибута PROTOCOL, но зато есть атрибут HREF.

    Обработка событий Mouseover и Mouseout

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

    В качестве обработчика события мы вызываем функцию line2(), которая идентична line1() из предыдущего примера. В примере IMG перенесен на новую строку для наглядности. На самом деле так поступать не следует — при интерпретации HTML-парсером могут появиться неучтенные пропуски, которые не предусмотрены автором страницы. (открыть)
    Обработка событий Mouseover и Mouseout
    Рис. 17.2. 
    Мы рассмотрели редкий пример, в котором не требуется возврата предыдущего значения после прохода мыши по гипертекстовой ссылке. По этой причине в гипертекстовой ссылке не применялся второй обработчик onMouseout. В большинстве случаев, например при расцвечивании картинки, он требуется:

    Рассматривая предыдущий пример, мы не обсудили использование функции return. При работе с графикой значение, которое возвращает обработчик события, на результат отображения не влияет. Но если изменять значение поля статуса браузера, то изменения произойдут только в случае возврата значения true. Более подробно об этом рассказано в разделе "Поле статуса".

    Обработка события click

    Вообще говоря, обработчик события click в современном JavaScript не нужен. Можно прекрасно обойтись URL-схемой javascript, которая была специально придумана для перехвата события гипертекстового перехода. Обработчик onClick следует рассматривать как реликт, доставшийся нам в наследство от предыдущих версий языка, который поддерживается в версиях Netscape Navigator и Internet Explorer.
    Основная задача обработчика данного события — перехват события гипертекстового перехода. Если функция обработки данного события возвращает значение true, то переход происходит, при значении false — не происходит:
    Отменим переход в начало страницы описания события обработчика onClick:
    onClick
    А теперь дадим пользователю право выбора перехода в начало страницы посредством окна подтверждения:
    переход в начало страницы
    Обратите внимание на место применения функции window.confirm() — аргумент команды return. Логика проста: функция возвращает значение true или false, и именно оно подставляется в качестве аргумента. Если просто написать функцию без return, то ничего работать не будет.
    Можно ли вообще обойтись одним обработчиком onClick без использования атрибута HREF? Видимо, нет. Первое, что необходимо браузеру — это определение типа контейнера A. Если в нем есть только атрибут NAME, то это якорь, если присутствует атрибут HREF — ссылка. Это два разных объекта. Они имеют различные составляющие, в том числе и обработчики событий. В контексте текущего раздела нам нужна именно ссылка, т.е. контейнер A с атрибутом HREF. Проверим наше предположение:
    Нет атрибута HREF
    Текст "Нет атрибута HREF" — это якорь. Обработчик на нем не работает, так как на него нельзя указать мышью.
    Нет атрибута HREF
    Теперь мы указали пустую ссылку (см. поле статуса). Содержание окна — это база URL.

    Схема URL- "javascript:..."

    Для программирования гипертекстовых переходов в спецификацию универсального идентификатора ресурсов (URL) разработчики JavaScript ввели отдельную схему по аналогии со схемами http, ftp и т.п. — javascript. Эта схема URL упоминается в разделе "Размещение JavaScript-кода" в контексте передачи управления JavaScript-интерпретатору от HTML-парсера. Кроме того, о программировании гипертекстового перехода рассказано в разделе "Обработка события click". Теперь мы рассмотрим более общий случай обработки события гипертекстового перехода при выборе гипертекстовой ссылки.
    Схема URL javascript в общем виде выглядит следующим образом:
    ...

    Одним словом, в любом месте, где мы используем URL, вместо любой из стандартных схем можно применить схему javascript. Единственное исключение составляет контейнер IMG. URL в нем используется в атрибуте SRC. Принять определенное значение SRC может при помощи либо назначения в IMG, либо обращения к свойству IMG. По большому счету, применение JavaScript в SRC может только проинициализировать картинку. Дальнейшее ее изменение описано в разделе "Программируем графику". Рассмотрим пример простой гипертекстовой ссылки:
    Заменили обычную ссылку
    Можно выполнить аналогичную операцию, но над картинкой:
    var flag=0; function ichange() { if(flag==0) { document.i1.src="image1.gif"; flag=1; } else { document.i1.src="image2.gif"; flag=0; } } ...
    Попробуем теперь выполнить JavaScript-код применительно к контейнеру FORM:
    Введите текст для отображения в окне и нажмите ввод:


    Замена атрибута HREF

    В разделе "Программируем ссылки" мы перечислили свойства объекта класса Link. Теперь покажем, как при помощи JavaScript-кода можно ими управлять. Рассмотрим меню типа "записная книжка": (открыть)
    Замена атрибута HREF
    Рис. 17.1. 
    Конечно, это не настоящая "записная книжка". Поле формы заполняется только при выборе гипертекстовой ссылки, расположенной над этим полем. Единственная цель данного примера — показать, как изменяется значение атрибута HREF (оно отображается в поле status окна браузера). Изменение производится посредством вызова функции:
    Пример 17.1.
    (html, txt)
    В данном случае мы работаем с тремя элементами массива встроенных гипертекстовых ссылок: all['lo0'], all['lo1'] и all['lo2']. У каждого из них при вызове функции со значением аргумента a, равным 0, 1 и 2, соответственно, изменяем значение свойства href. Это свойство мы меняем целиком. URL можно менять и частично.

    Введение в JavaScript

    Break

    Оператор break позволяет досрочно покинуть тело цикла. Распечатаем только title документа:
    for(v in window.document) if(v=="title") { document.write(v+":"+eval('document.'+v)+" "); break; }
    Результат исполнения:
    title:Web-engineering (Introduction to the JavaScript. Operators.).
    В пример распечатки свойств объекта   document мы вставили break при просмотре свойства title и получили искомый результат.

    Continue

    Того же результата, что и при использовании break, можно было бы достичь при помощи оператора continue:
    for(v in window.document) { if(v!="title") continue; document.write(v+":"+eval('document.'+v)); break; }
    Результат исполнения:
    title:Web-engineering (Introduction to the JavaScript. Operators.)
    Этот оператор позволяет пропустить часть тела цикла (от оператора до конца тела) и перейти к новой итерации. Таким образом мы просто пропускаем все свойства до title и после этого выходим из цикла.

    Фокус в полях формы

    Управление фокусом в полях формы, кроме этого раздела, описано еще и в разделе "Текст в полях ввода". Здесь мы рассматриваем этот вопрос в контексте общего применения методов blur() и focus(). Эти методы определены для любого поля формы, а не только для полей ввода. Рассмотрим простой пример.
    Попробуйте изменить в этой форме значение любого из полей. Вряд ли это вам удастся. Обработчик события Focus (onFocus) уводит фокус из поля на произвольное место страницы.

    For ... in

    Данный оператор позволяет "пробежаться" по свойствам объекта. Рассмотрим пример:
    for(v in window.document) { document.write(v+"
    "); }
    Все свойства текущего объекта "документ":
    Пример 18.4.
    (html, txt)
    Данный документ состоит из нескольких разделов. Обращение "window.document" позволяет обратиться к общему документу, а не к отдельно взятому разделу. Поэтому распечатанные свойства — это свойства всего документа.

    For

    Оператор for — это еще один оператор цикла. В общем случае он имеет вид:
    for (инициализация переменных цикла; условие; модификация переменных цикла) оператор;
    Оператор в теле цикла может быть блоком. Рассмотрим типичный пример использования этого оператора:
    for(i=0;i"); } http://intuit.ru/help/index.html http://intuit.ru/help/shop.html#choice http://intuit.ru/help/payment.html
    Подобные примеры разбросаны по всем разделам курса.

    Функции

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

  • функция — тип данных;

  • функция — объект;
  • конструкторы объектов.

  • Именно эти вопросы мы и рассмотрим в данном разделе.

    Функция — объект

    У любого типа данных JavaScript существует объектовая "обертка" — Wrapper, которая позволяет применять методы типов данных к переменным и литералам, а также получать значения их свойств. Например, длина строки символов определяется свойством length. Аналогичная "обертка" есть и у функций — объект   Function.
    Например, увидеть значение функции можно не только при помощи метода valueOf(), но и используя метод toString():
    function f_name(x,y) { return x-y; } document.write(f_name.toString()+"
    ");
    Результат распечатки:
    function f_name(x,y) { return x-y; }
    Свойства функции доступны для программиста только тогда, когда они вызываются внутри функции. При этом обычно программисты имеют дело с массивом аргументов функции (arguments[]), его длиной (length), именем функции, вызвавшей данную функцию (caller)и прототипом (prototype).
    Рассмотрим пример использования списка аргументов функции и его длину:
    function my_sort() { a = new Array(my_sort.arguments.length); for(i=0;i");
    Результат исполнения:
    b[0]=2 b[1]=3 b[2]=5 b[3]=7 b[4]=9
    Если функция может быть вызвана из других функций, то в этом случае используется свойство caller:
    function slave() { document.write(slave.caller+""); return slave.caller; } function master1() { slave(); } function master2() { slave(); } ... master1(); master2();
    Результат исполнения двух последних строк:
    function master1() { slave(); } function master2() { slave(); }
    Еще одним свойством объекта   Function является prototype, но это общее свойство всех объектов, поэтому и обсуждать его мы будем в контексте типа данных   Object. Упомянем только о конструкторе объекта   Function:
    f = new Function(arg_1,...,arg_n, body)
    Здесь f — это объект класса Function. Его можно использовать и как обычную функцию. Конструктор используют для получения безымянных функций, которые назначают или переопределяют методы объектов. Здесь мы вплотную подошли к вопросу конструирования объектов. Дело в том, что переменные внутри функции можно рассматривать в качестве ее свойств, а функции – в качестве методов:

    Функция — тип данных

    Определяют функцию при помощи ключевого слова function:
    function f_name(arg1,arg2,...) { /* function body */ }
    Здесь следует обратить внимание на следующие моменты. Во-первых, function определяет переменную f_name. Эта переменная имеет тип "function":
    document.write("Тип переменной f_name:"+ typeof(f_name));
    Тип переменной f_name: function. Во-вторых, этой переменной присваивается значение:
    document.write("Значение i:"+i.valueOf()); document.write("Значение f_name:"+ f_name.valueOf());
    Значение переменной f_name: 10. Значение переменной f_name:function f_name(a) { if(a>=0) return true; else return false; }. В данном случае метод valueOf() применяется как к числовой переменной i, так и к f_name. По этой причине функции можно назначить синоним путем присваивания ее значения другой переменной:
    function f_name(a) { if(a>=0) return true; else return false; } document.write("Значение переменной f_name:"+ f_name(1)+""); b = f_name; document.write("Значение переменной b:"+ b(1)+""); Значение переменной f_name:true Значение переменной b:true
    Очевидно, что если функцию можно присвоить переменной, то ее можно передать и в качестве аргумента другой функции. Все это усиливается при использовании функции eval(), которая позволяет реализовать отложенное исполнение JavaScript-кода. Отложенное исполнение — это возможность изменения программы по ходу ее исполнения. Типичным использованием eval() является сокращение кода за счет генерации однотипных строк:
    for(i=0;i<5;i++) { eval("document.write('test"+i+"
    ')"); }
    Результат исполнения кода:
    test0 test1 test2 test3 test4
    При непосредственном кодировании пришлось бы написать пять строк кода. Данный подход использовался в разделе "Изменение картинки" для инициирования массивов картинок, имена которых построены по принципу индексации ячеек таблицы.

    If

    Условный оператор применяется для ветвления программы по некоторому логическому условию. Общий синтаксис:
    if (логическое выражение) оператор1; [else оператор2;]
    Логическое выражение — это выражение, которое принимает значение true или false. Если оно равно true, то оператор 1 исполняется. В квадратных скобках необязательная составляющая оператора if — альтернатива основной ветви вычислений:
    if (navigator.appName=="Netscape") { window.location.href= "http://intuit.ru/netscape.htm"; } else { window.location.href= "http://intuit.ru/explorer.htm"; }
    Примеры использования условного оператора можно найти, например, в разделе "Тип браузера".

    Код во внешнем файле

    Попав на данную страницу, вы уже использовали программу из внешнего файла. Чтобы убедиться в этом, достаточно посмотреть на HTML-разметку данной страницы:
    ... ... ...
    Контейнер SCRIPT определяет внешний файл размещения скриптов. Функция jump() расположена именно в этом файле. Она анализирует ссылку на данный документ, и если в ней есть компонент hash(#), то она продергивает файл до якоря, указанного в hash. Чтобы в этом убедиться, перейдите по любой внутренней ссылке, например, из меню разбивки раздела на подразделы, а после этого перезагрузите документ по Ctrl+R. Сначала документ будет загружен, а потом прокручен до указанного якоря.

    Литералы

    Литералом называют данные, которые используются в программе непосредственно. При этом под данными понимаются числа или строки текста. Все они рассматриваются в JavaScript как элементарные типы данных. Приведем примеры литералов:
    числовой литерал: 10 числовой литерал: 2.310 числовой литерал: 2.3e+2 строковый литерал: 'Это строковый литерал' строковый литерал: "Это строковый литерал"
    Литералы используются в операциях присваивания значений переменным или в операциях сравнения:
    var a=10; var str = 'Строка'; if(x=='test') window.alert(x);
    Два варианта строковых литералов необходимы для того, чтобы использовать вложенные строковые литералы. Вообще говоря, есть подозрение, что равноправие "..." и '...' мнимое. Если внимательно посмотреть на реализацию страниц программирования гипертекстовых ссылок (href.htm, path.htm и mouse.htm), можно заметить, что вместо прямого переназначения гипертекстовой ссылки литералом типа '...' там используется косвенное переназначение через функцию литералом "...":
    ... function line(a) { ... window.document.main.document.links[4].href= "javascript:data(0);void(0);"; ... } ...
    вместо:

    Это связано с особенностями реализации Netscape. Дело в том, что прямое переназначение неправильно отображает кириллицу в win32, а вот косвенное работает. Похоже, что "..." разрешает анализ информации внутри строкового литерала JavaScript-интерпретатором, а '...' — нет.
    Если быть более точным, то следует сказать, что строка — это объект. У этого объекта существует великое множество методов. Строчный литерал и строчный объект — далеко не одно и то же. При применении к строчным литералам методов строчных объектов происходит преобразование первых в последние.

    Массивы

    Массивы делятся на встроенные (document.links[], document.images[],...) и определяемые пользователем (автором документа). Встроенные массивы мы подробно обсуждаем в разделах "Программируем картинки", "Программируем формы" и "Программируем гипертекстовые переходы". Поэтому подробно остановимся на массивах, определяемых пользователем. Для массивов задано несколько методов:

  • join();

  • reverse();

  • sort();

  • и свойство length, которое позволяет получить число элементов массива. Это свойство активно используется в примерах данного раздела. В частности, при обсуждении метода join().
    Для определения массива пользователя существует специальный конструктор:
    a = new Array(); b = new Array(10); c = new Array(10,"Это значение");
    Пример использования:

    Как видно из этого примера, массив может состоять из разнородных элементов. Массивы не могут быть многомерными.
    Для работы с массивами в JavaScript применяются методы join(), reverse(), sort(). Кроме того, массивы обладают свойством длины, length.

    Метод join()

    Метод join() позволяет объединить элементы массива в одну строку. Он является обратной функцией методу split(), который применяется к объектам типа STRING. Рассмотрим пример преобразования локального URL в URL схемы http:
    window.location: http://intuit.ru/help/index.html
    Выполнили:
    b = window.location.href.split('/');
    Получили массив b:
    b[0]=http: b[1]= b[2]=intuit.ru b[3]=help b[4]=index.html
    Заменили схему и вставили "host:port":
    for(i=0;i Получили массив b:
    b[0]=http: b[1]= b[2]=intuit.ru b[3]=help b[4]=index.html
    Слили элементы массива b:
    l=b.join("/");
    Получили в результате:
    http://intuit.ru/help/index.html
    Другой пример использования метода join() — замена символа в строке:
    str = "document.img1.src= 'http://images/imagе1.gif';" document.write(str);
    Исходная строка:
    document.img1.src='http://images/imagе1.gif';
    Заменяем в строке все единицы на двойки:
    b = str.split('1'); str = b.join('2');
    Получаем следующий результат:
    document.img2.src='http://images/imagе2.gif';
    Последний пример показывает, что массив пользователя можно получить и без явного применения конструктора массива. Массив элементов строки получается просто как результат действия функции split().

    Метод reverse()

    Метод reverse() применяется для изменения на противоположный порядка элементов массива внутри массива. Предположим, массив натуральных чисел упорядочен по возрастанию:
    a = new Array(1,2,3,4,5);
    Упорядочим его по убыванию:
    a.reverse(); a[0]=5 a[1]=4 a[2]=3 a[3]=2 a[4]=1
    Можно, наверное, придумать и более внятный пример, но, к сожалению, на практике встречаться с этим методом мне приходилось нечасто.

    Метод sort()

    Как принято в современных интерпретируемых языках, например в Perl, метод sort() позволяет отсортировать элементы массива в соответствии с некоторой функцией сортировки, чье имя используется в качестве аргумента метода:
    a = new Array(1,6,9,9,3,5); function g(a,b) { if(a > b) return 1; if(a < b) return -1; if(a==b) return 0; } b = a.sort(g);
    В результате выполнения этого кода получим массив следующего вида:
    b[0]=1 b[1]=3 b[2]=5 b[3]=6 b[4]=9 b[5]=9
    Возможность использования произвольной функции сортировки позволяет выполнять подробный анализ строковых объектов. Одним из таких примеров может служить анализ строки атрибута SRC контейнера IMG, если картинка подставляется скриптом, и сортировка полей формы по значениям:
    document.image.src = "http://www.intuit.ru:80/cgi-bin/ image?x=10&y=20&z=15";
    Выделим x и y. Затем отсортируем их:
    str = "http://www.intuit.ru:80/cgi-bin/ image?x=10&y=20&z=15"; s = str.split('?'); s1 = s[1].split('&'); s2 = s1.sort(g); for(i=0;i"); s2[0]='x=10' s2[1]='z=15' s2[2]='y=20'
    Аналогичные манипуляции можно проделать с любым массивом. Если не указывать функции в аргументе метода сортировки, то элементы массива сортируются в лексикографическом порядке. Это значит, что они сначала преобразуются в строки и только потом сортируются.

    Методы объекта Object

    Object — это объект и, следовательно, у него могут быть методы. Таких методов мы рассмотрим три: toString(), valueOf() и assign().
    Метод toString() осуществляет преобразование объекта в строку символов. Он используется в JavaScript-программах повсеместно, но неявно. Например, при выводе числа или строковых объектов. Интересно применение toString() к функциям:
    document.write(prot.toString()+"
    ");
    Результат исполнения:
    function prot() { a = this.src.split(':'); protocol = a[0]+":"; return protocol; }
    Здесь мы используем функцию   prot() из примера с прототипом. Если распечатать таким же образом объект   Image, то получим следующее:
    картинка:[object]
    Таким образом, далеко не всегда метод toString() возвращает строковый эквивалент содержания объекта. Он может просто вернуть его тип. Internet Ехplorer при этом возвращает "Object", в то время как Netscape Navigator — "object Image".
    Аналогично ведет себя и метод valueOf(). Этот метод позволяет получить значение объекта. В большинстве случаев он работает подобно методу toString(), особенно если нужно выводить значение на страницу:
    document.write(prot.valueOf()+"
    ");
    Результат исполнения:
    function prot() { a = this.src.split(':'); protocol = a[0]+":"; return protocol; }
    Как видим, результат тот же, что и в методе toString().
    В отличие от двух предыдущих методов, assign() позволяет не прочитать, а переназначить свойства и методы объекта. Данный метод используется в контексте присваивания объекту некоторого значения:
    object = value; <=> object.assign(value);
    Рассмотрим пример:
    c = new Image(); c.src = "image1.gif"; b =new Image(); b.src = "image2.gif"; Image.prototype.assign = new Function("a","this.src = a.src;"); ... Покрасить картинку
    В данном примере мы применяем метод assign() не внутри JavaScript-кода, а в обычной HTML-разметке. При этом перед использованием метода мы переопределили его своей функцией. Пользователей Internet Explorer следует предупредить, что здесь мы их немножко обманываем, так как переназначить прототип Image в Internet Explorer мы в данном случае не можем.

    Модель безопасности

    При программировании на JavaScript потенциально существует возможность доступа из программы к персональной информации пользователя. Такая проблема возникает всегда, когда нечто, запускаемое на компьютере, имеет возможность самостоятельно организовать обмен данными по сети с удаленным сервером.
    От версии к версии управление защитой таких данных постоянно совершенствуется, но всегда нужно иметь в виду, что множество "следопытов" исследует эту проблему и постоянно открывает все новые и новые возможности обхода механизмов защиты.
    Объясним только основные моменты в принципах защиты информации в JavaScript, а поиск потенциально слабых мест оставим в качестве домашнего задания для наиболее пытливых читателей.
    По умолчанию к защищенным в JavaScript данным относятся:
    ОбъектСвойства
    Documentcookie, domain, forms[], lastModified, links[], location, referer, title, URL
    Formaction
    document.forms [].elements[]checked, defaultChecked, defaultValue, name, selectedIndex, toString, value
    Historycurrent, next, previous, toString(), all array elements
    Location, Link, Areahash, host, hostname, href, pathname, port, protocol, search, toString()
    OptiondefaultSelected, selected, text, value
    WindowdefaultStatus, status

    Защищенными эти данные являются с той точки зрения, что программа не может получить значения соответствующих атрибутов. Главным образом речь здесь идет о программе, которая пытается получить доступ к данным, которые определены на другой странице (не на той, в рамках которой данная программа исполняется). Например, к данным из другого окна.
    В настоящее время известны три модели защиты: запрет на доступ (Navigator 2.0), taint model (Navigator 3.0), защита через Java (Navigator 4.0). Применение моделей и соответствующие приемы программирования — это отдельный сложный вопрос, требующий знаний и навыков программирования на языке Java, поэтому в рамках данного курса мы его рассматривать не будем.
    Отметим только, что к большинству свойств объектов текущей страницы и окна программист имеет доступ. Они становятся защищенными только в том случае, если относятся к документу в другом окне и загруженному из другого Web-узла. Поэтому ограничения, накладываемые системой безопасности JavaScript, достаточно гибкие и не очень сильно мешают разработке страниц с применением этого языка программирования.

    Невидимый фрейм

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

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

    Невидимый код

    Вопрос доступности JavaScript-кода рассматривается с двух точек зрения: идентификация, как следствие — необходимость сокрытия кода, и безопасность пользователя, следовательно — доступность кода.
    Приемы программирования со скрытым кодом позволяют решить еще несколько задач, которые не связаны с безопасностью.
    Мы будем рассматривать возможность использования скрытого кода без выдачи вердиктов о преимуществе того или иного подхода. Рассмотрим несколько вариантов:
  • невидимый фрейм;
  • код во внешнем файле;

  • обмен данными посредством встроенной графики.

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

    Объекты

    Объект — это главный тип данных JavaScript. Любой другой тип данных имеет объектовую "обертку" — Wrapper. Это означает, что прежде чем можно будет получить доступ к значению переменной того или иного типа, происходит конвертирование переменной в объект, и только после этого выполняются действия над значением. Тип данных   Object сам определяет объекты.
    В данном разделе мы остановимся на трех основных моментах:
  • понятие объекта;

  • прототип объекта;
  • методы объекта   Object.

  • Мы не будем очень подробно вникать во все эти моменты, так как при программировании на стороне браузера чаще всего обходятся встроенными средствами JavaScript. Но поскольку все эти средства — объекты, нам нужно понимать, с чем мы имеем дело.

    Обмен данными посредством встроенной графики

    Данный прием основан на двух идеях: возможности подкачки графического образа без перезагрузки страницы и возможности подкачки этого графического образа не через указание URL графического файла, а через CGI-скрипт, который возвращает Content-type: image/... или осуществляет перенаправление.
    При этом следует учитывать, что использовать метод, отличный от GET, можно только в формах, а мы хотим просто менять значение свойства src:
    ... function change_image(x) { s = "http://intuit.ru/cgi-bin/image_script?"+ document.cookie; document.x.src= s; ...
    Эта безобидная последовательность операторов JavaScript позволит нам узнать получил ли клиент cookie. "Волшебные ключики" могут не поддерживаться по разным причинам. В данном случае программа передает на сервер выставленные им "ключики" в качестве параметра скрипта под видом изменения картинки.

    Операторы языка

    В этом разделе будут рассмотрены операторы JavaScript. Основное внимание при этом мы уделим операторам декларирования и управления потоком вычислений. Без них не может быть написана ни одна JavaScript-программа.
    Общий перечень этих операторов выглядит следующим образом:

  • var;

  • {...};

  • if;

  • while;

  • for;

  • for ... in;

  • break;

  • continue;

  • return.

  • Сразу оговоримся, что этот список неполный.

    Переменные

    Переменные в JavaScript могут быть определены назначением или при помощи оператора var:
    i=10; var i; var i=10; var id = window.open(); var a = new Array();
    Как видно из примеров, переменные могут принимать самые разные значения, при этом тип переменной определяется контекстом.
    Переменная является свойством окна. Например, мы можем открыть окно, определить в нем новую переменную и использовать ее:
    Пример 18.1.
    (html, txt)
    Существуют ли в JavaScript различные типы переменных? По всей видимости, да. При объявлении переменной тип не указывается. Тип значения определяется контекстом, поэтому можно было бы предположить, что все переменные — одного и того же типа. Однако очевидно, что присваивание переменной значения объекта окна (window.open()) или объекта потока (setTimeout()), вызывает создание в памяти совершенно разных структур.
    Поставим вопрос несколько иначе. Может ли одна и та же переменная принимать значения разных типов? Для ответа на этот вопрос рассмотрим следующий пример:
    Пример 18.2.
    (html, txt)
    Можно в любом порядке нажимать на кнопки формы, и все будет работать правильно. При этом переменная cid используется и как идентификатор потока, и как идентификатор окна. Это означает, что JavaScript все-таки поддерживает полиморфизм, т.е. существует два разных объекта с одинаковыми именами, и система в них не путается.

    Понятие объекта

    Сначала рассмотрим пример произвольного, определенного пользователем объекта, потом выясним, что же это такое:
    function Rectangle(a,b,c,d) { this.x0 = a; this.y0 = b; this.x1 = c; this.y1 = d; this.area = new Function( "return Math.abs(this.x0-this.x1)* Math.abs(this.y0-this.y1)"); this.perimeter = new Function( "return (Math.abs(this.x0-this.x1) + Math.abs(this.y0-this.y1))*2"); } c = new Rectangle(0,0,100,100); document.write(c.area());
    Результат исполнения:
    10000
    Этот же пример использовался в разделе "Функции" для иллюстрации применения конструктора функции. Здесь мы рассмотрим его в более общем контексте.
    Функция   rectangle() — это конструктор объекта класса Rectangle, который определяется пользователем. Конструктор позволяет создать реальный объект данного класса. Ведь функция — это не более чем описание некоторых действий. Для того чтобы эти действия были выполнены, необходимо передать функции управление. В нашем примере это делается при помощи оператора new . Он вызывает функцию и тем самым генерирует реальный объект.
    Создается четыре переменных: x0, y0, x1, y1 — это свойства объекта   Rectangle. К ним можно получить доступ только в контексте объекта данного класса, например:
    up_left_x = c.x0; up_left_y = c.y0;
    Кроме свойств мы определили внутри конструктора два объекта типа Function(), применив встроенные конструкторы языка JavaScript, — area и perimeter. Это методы объекта данного класса. Вызвать эти функции можно только в контексте объекта класса Rectangle:
    sq = c.area(); length = c.perimeter();
    Таким образом, объект — это совокупность свойств и методов, доступ к которым можно получить, только создав при помощи конструктора объект данного класса и использовав его контекст.
    На практике довольно редко приходится иметь дело с объектами, созданными программистом. Дело в том, что объект создается функцией-конструктором, которая определяется на конкретной странице и, следовательно, все, что создается в рамках данной страницы, не может быть унаследовано другими страницами. Нужны очень веские основания, чтобы автор Web-узла занялся разработкой библиотеки классов объектов пользователя. Гораздо проще писать функции для каждой страницы.

    Закрыть окно'

    wid = window.open("","test","width=200,height=100,statusbar"); wid.document.open(); wid.document.write(" "); wid.document.write(""); wid.document.write(""); wid.document.write("
    Новое окно
    "); wid.document.write("
    "); wid.document.write("
    "); wid.document.write("
    "); wid.document.close(); ... ...
    Пример 18.1.
    Закрыть окно

    var flag= 0; var cid=null; function clock() { flag=1; d = new Date(); window.document.main.document.f0.fi1.value= d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(); cid = setTimeout("clock();",10000); } function stop() { if(cid!=null) { clearTimeout(cid); cid=null; flag=0; } } function wo() { cid = window.open("","test","width=400,height=100"); cid.document.open(); cid.document.write("
    "); cid.document.write("
    "); cid.document.write(""); cid.document.close(); cid.focus(); } ...
    Пример 18.2.
    Закрыть окно

    function prot() { a = this.src.split(':'); protocol = a[0]+":"; return protocol; } function host() { a = this.src.split(':'); path = a[1].split('/'); return path[2]; } function pathname() { a = this.src.split(':'); path = a[1].split('/'); b = new array(); for(i=3;i
    "); document.write(document.i1.src+"
    "); document.write(document.i1.protocol()+"
    "); document.write(document.i1.host()+"
    "); document.write(document.i1.pathname()+"
    ");
    Пример 18.3.
    Закрыть окно

    namespaces:[object] lastModified:07/16/2002 21:22:53 onmousedown:null URLUnencoded:http://intuit.ru/help/index.html fileCreatedDate:07/16/2002 onbeforeeditfocus:null bgColor:#ffffff oncontextmenu:null onrowexit:null embeds:[object] scripts:[object] mimeType:HTML Document alinkColor:#0000ff onmousemove:null onselectstart:null oncontrolselect:null body:[object] protocol:HyperText Transfer Protocol onkeypress:null onrowenter:null vlinkColor:#800080 URL:http://intuit.ru/help/index.html onreadystatechange:null applets:[object] domain:intuit.ru fileModifiedDate:07/16/2002 onmouseover:null dir: media: defaultCharset:windows-1251 plugins:[object] ondragstart:null oncellchange:null cookie:hotlog=1; hotlog=1; b=b documentElement:[object] ondatasetcomplete:null nameProp:Web-engineering (Introduction to the JavaScript. Operators.) referrer:http://intuit.ru/help/index.html onrowsdelete:null onerrorupdate:null onselectionchange:null ondblclick:null onkeyup:null location:http://intuit.ru/help/index.html forms:[object] title:Web-engineering (Introduction to the JavaScript. Operators.) onrowsinserted:null onmouseup:null onkeydown:null fgColor:#000080 ondatasetchanged:null onmouseout:null parentWindow:[object] fileUpdatedDate:01/01/1601 onpropertychange:null onstop:null onhelp:null linkColor:#0000ff images:[object] readyState:interactive frames:[object] all:[object] onclick:null childNodes:[object] anchors:[object] selection:[object] onbeforeupdate:null security: This type of document does not have a security certificate. fileSize:15911 ondataavailable:null styleSheets:[object] activeElement:null links:[object] onafterupdate:null sea001:[object]onafterupdate:null down:[object]onafterupdate:null
    Пример 18.4.
    Закрыть окно

    Прототип

    Обычно мы имеем дело со встроенными объектами JavaScript. Собственно, все, что изложено в других разделах курса — это обращение к свойствам и методам встроенных объектов. В этом смысле интересно свойство объектов, которое носит название prototype. Прототип — это другое название конструктора объекта конкретного класса. Например, если мы хотим добавить метод к объекту класса String:
    String.prototype.out = new Function("a", "a.write(this)"); ... "Привет!".out(document);
    Результат исполнения:
    Привет!
    Для объявления нового метода для объектов класса String мы применили конструктор Function. Есть один существенный нюанс: новыми методами и свойствами будут обладать только те объекты, которые порождаются после изменения прототипа объекта. Все встроенные объекты создаются до того, как JavaScript-программа получит управление, что существенно ограничивает применение свойства prototype.
    Тем не менее покажем, как можно добавить метод к встроенному в JavaScript классу объектов. Примером будет служить встроенный поименованный Image. Задача состоит в том, чтобы разобрать URL картинки таким же образом, как и URL объекта класса Link:
    Пример 18.3.
    (html, txt)
    Основная идея заключается в том, чтобы переопределить конструктор раньше, чем он будет использован. HTML-парсер разбирает HTML и создает встроенные объекты раньше, чем запускается JavaScript-интерпретатор. Из этого следует, что объект на странице нужно создать через JavaScript-код. В этом случае сначала происходит переопределение объекта   Image, а уже после этого создается встроенный объект данного класса. При работе с Internet Explorer все иначе. Если на свойство prototype у строкового объекта он не "ругается", то для Image такое свойство уже не определено.

    Return

    Оператор return используют для возврата значения из функции или обработчика события (см. разделы "Поле статуса", "Обмен данными"). Рассмотрим пример:

    В данном примере return используется для маскирования передачи данных на сервер.

    Скрытая передача данных из форм

    Обмен данными в Web-технологии подробно рассматривается в другой главе — "CGI и формы". Программирование элементов форм обсуждается в разделе "Программируем формы". В этом разделе мы рассмотрим вопрос о возможности передачи скрытых от пользователя данных.
    Рассмотрим следующий пример. Нажмите на кнопку "Подписка" и посмотрите на строку location своего браузера. Вы обнаружите там два поля, которых нет в заполняемой вами форме: h1 и h2. Это уже неприятно, хотя сама информация в них отнюдь не криминальная (location.href и document.referer). Это означает, что в тексте страницы есть вызов функции со строками типа:

    Теперь посмотрим другой пример. Если начать вводить данные в левом фрейме окна примера, то, как только вы переходите от поля к полю, в правом фрейме заполняются соответствующие поля. Cкрипт из правого фрейма читает данные из полей левого фрейма. В кодах это будет выглядеть примерно так:
    function ask() { document.forms[0].elements[0].value= window.top.frames[0].document.forms[0 ].elements[0].value; document.forms[0].elements[1].value= window.top.frames[0].document.forms[0 ].elements[1].value; document.forms[0].elements[2].value= window.top.frames[0].document.forms[0 ].elements[2].value; document.forms[0].elements[3].value= window.top.frames[0].document.forms[0 ].elements[3].value; setTimeout("ask();",100); } ...
    Это означает, что данные из одного окна могут быть считаны программой из другого окна. Вопрос только в том, хотите ли вы, чтобы это происходило. Как решаются эти вопросы, рассказано в разделе "Модель безопасности".
    Еще один пример — отправка данных по событию без наличия какой-либо формы в документе вообще.
    Нажми на ссылку
    Результат исполнения:
    Нажми на ссылку
    Согласно примеру при нажатии на гипертекстовую ссылку произойдет не только выдача сообщения, которое в этой ссылке указано, но и событие Submit для формы. В итоге вы получите два окна предупреждения. Но второе окно вы не заказывали!
    Конечно, бесконтрольной передачи данных на сервер можно избежать, введя режим подтверждения отправки. Но, во-первых, многие пользователи его отключают, а во-вторых, можно использовать не формы, а, например, графику. И эту возможность мы рассматриваем в разделе "Невидимый код".

    Типы и структуры данных

    Как и любой другой язык программирования, JavaScript поддерживает встроенные типы и структуры данных. Все их многообразие подразделяется на:
  • литералы и переменные;
  • массивы, функции и объекты.

  • При этом все они делятся на встроенные и определяемые программистом. Функции и объекты рассматриваются в разделах "Функции" и "Объекты". Поэтому здесь мы остановимся на литералах, переменных и массивах.

    Управление фокусом во фреймах

    Фрейм — это такое же окно, как и само окно браузера. Точнее — это объект того же класса. К нему применимы те же методы, что и к обычному объекту "окно":
    var flag=1; function clock() { if(flag==0) { d=new Date(); s=d.getHours()+':'+d.getMinutes()+':'+ d.getSeconds(); window.document.forms[0].elements[0].value=s; } setTimeout('clock();',100); } window.onblur = new Function('this.flag = 1;'); window.onfocus = new Function('this.flag = 0;'); window.onload = clock;
    Данный фрагмент кода размещен в каждом из двух фреймов, которые отображаются в примере. А их именно два. Просто ширина границы набора фреймов установлена в 0. Если окно примера разделить мысленно пополам и "кликнуть" мышью в одну из половин, то пойдут часы в этой половине. Если теперь переместиться в другой фрейм и "кликнуть" мышью в нем, то часы пойдут в поле формы этого фрейма, а в другом фрейме остановятся.

    Управление фокусом

    Фокус — это характеристика текущего окна, фрейма или поля формы. В каждом из разделов, описывающем программирование этих объектов, мы, так или иначе, касаемся вопроса фокуса. Под фокусом понимают возможность активизации свойств и методов объекта. Например, окно в фокусе, если оно является текущим, т.е. лежит поверх всех других окон и исполняются его методы или можно получить доступ к его свойствам.
    В данном разделе мы рассмотрим управление фокусом в
  • окнах;
  • фреймах;
  • полях формы.

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

    Управляем фокусом в окнах

    Для управления фокусом у объекта класса "окно" существует два метода: focus() и blur(). Первый передает фокус в окно, в то время как второй фокус из окна убирает. Рассмотрим простой пример:
    function hide_window() { wid=window.open("","test", "width=400,height=200"); wid.opener.focus(); wid.document.open(); ... wid.document.close(); }
    В данном примере новое окно открывается и сразу теряет фокус; прячется за основным окном-родителем. Если при первичном нажатии на кнопку оно еще всплывает и только после этого прячется, то при повторном нажатии пользователь не видит появления нового окна, так как оно уже открыто и меняется только его содержимое.
    Для того чтобы этого не происходило, нужно после открытия передавать фокус на новое окно:
    function visible_window() { wid=window.open("","test", "width=400,height=200"); wid.focus(); wid.document.open(); ... wid.document.close(); }
    Если теперь нажимать попеременно кнопки "Скрытое окно" и "Видимое окно", окно будет то появляться, то исчезать. При этом новых окон не появляется, так как с одним и тем же именем может быть открыто только одно окно.
    Невидимое окно может доставить пользователю неприятности, из которых самая безобидная — отсутствие реакции на его действия. Код просто записывается в невидимое окно. Но ведь в скрытом окне можно что-нибудь и запустить. Для этого стоит только проверить, существует ли данное окно или нет, и если оно есть и не в фокусе, то активизировать в нем какую-нибудь программу.
    Для реализации такого сценария достаточно использовать метод окна onblur(). Его можно также задать в контейнере BODY в качестве обработчика события onBlur, но в этом случае он видим пользователю. Мы воспользуемся этим методом "в лоб":
    window.onblur = new Function("window.defaultStatus = 'Background started...';"); window.onfocus = new Function("window.defaultStatus = 'Document:Done';");
    Обратите внимание на поле статуса браузера. Оно демонстрирует возможность выполнения функции в фоновом режиме. Кроме того, onblur() в этом виде не отрабатывает в Internet Explorer. Причина кроется в прототипе объекта и возможности его переназначения программистом.
    Конечно, когда разработчики создавали всю эту конструкцию, думали не о том, как насолить пользователю, а о том, как сократить ресурсы, необходимые браузеру для отображения нескольких окон. Ведь можно выполнить все то же самое с точностью до наоборот: запускать, например, часы в фокусе и останавливать их в фоне. Но этот пример мы рассмотрим в контексте фреймов.

    Var

    Оператор var служит для объявления переменной. При этом переменная может принимать значения любого из разрешенных типов данных. На практике довольно часто обходятся без явного использования var. Переменная соответствующего типа создается путем простого присваивания:
    var a; var a=10; var a = new Array(); var a = new Image();
    Все перечисленные выше примеры использования var верны и могут быть применены в JavaScript-программе. Область действия переменной определяется блоком (составным оператором), в котором используется переменная. Максимальная область действия переменной — страница.

    While

    Оператор while определяет цикл. Определяется он в общем случае следующим образом:
    While (логическое выражение) оператор;
    Оператор, в том числе и составной, — тело цикла. Тело исполняется до тех пор, пока верно логическое условие:
    while (flag==0) { id=setTimeout ("test();",500); }
    Обычно цикл этого типа применяют при выполнении периодических действий до некоторого события.

    

        Бизнес: Предпринимательство - Малый бизнес - Управление