Модель объектов javascript объекты navigator’а


Содержание

Браузерное окружение, спецификации

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

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

Окружение предоставляет свои объекты и дополнительные функции, в дополнение базовым языковым. Браузеры, например, дают средства для управления веб-страницами. Node.js делает доступными какие-то серверные возможности и так далее.

На картинке ниже в общих чертах показано, что доступно для JavaScript в браузерном окружении:

Как мы видим, имеется корневой объект window , который выступает в 2 ролях:

  1. Во-первых, это глобальный объект для JavaScript-кода, об этом более подробно говорится в главе Глобальный объект.
  2. Во-вторых, он также представляет собой окно браузера и располагает методами для управления им.

Например, здесь мы используем window как глобальный объект:

А здесь мы используем window как объект окна браузера, чтобы узнать его высоту:

Существует гораздо больше свойств и методов для управления окном браузера. Мы рассмотрим их позднее.

DOM (Document Object Model)

Document Object Model, сокращённо DOM – объектная модель документа, которая представляет все содержимое страницы в виде объектов, которые можно менять.

Объект document – основная «входная точка». С его помощью мы можем что-то создавать или менять на странице.

Мы использовали в примере только document.body.style , но на самом деле возможности по управлению страницей намного шире. Различные свойства и методы описаны в спецификации:

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

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

Правила стилей CSS структурированы иначе чем HTML. Для них есть отдельная спецификация CSSOM, которая объясняет, как стили должны представляться в виде объектов, как их читать и писать.

CSSOM используется вместе с DOM при изменении стилей документа. В реальности CSSOM требуется редко, обычно правила CSS статичны. Мы редко добавляем/удаляем стили из JavaScript, но и это возможно.

BOM (Browser Object Model)

Объектная модель браузера (Browser Object Model, BOM) – это дополнительные объекты, предоставляемые браузером (окружением), чтобы работать со всем, кроме документа.

  • Объект navigator даёт информацию о самом браузере и операционной системе. Среди множества его свойств самыми известными являются: navigator.userAgent – информация о текущем браузере, и navigator.platform – информация о платформе (может помочь в понимании того, в какой ОС открыт браузер – Windows/Linux/Mac и так далее).
  • Объект location позволяет получить текущий URL и перенаправить браузер по новому адресу.

Вот как мы можем использовать объект location :

Функции alert/confirm/prompt тоже являются частью BOM: они не относятся непосредственно к странице, но представляют собой методы объекта окна браузера для коммуникации с пользователем.

BOM является частью общей спецификации HTML.

Да, вы всё верно услышали. Спецификация HTML по адресу https://html.spec.whatwg.org не только про «язык HTML» (теги, атрибуты), она также покрывает целое множество объектов, методов и специфичных для каждого браузера расширений DOM. Это всё «HTML в широком смысле». Для некоторых вещей есть отдельные спецификации, перечисленные на https://spec.whatwg.org.

Итого

Говоря о стандартах, у нас есть:

Спецификация DOM описывает структуру документа, манипуляции с контентом и события, подробнее на https://dom.spec.whatwg.org. Спецификация CSSOM Описывает файлы стилей, правила написания стилей и манипуляций с ними, а также то, как это всё связано со страницей, подробнее на https://www.w3.org/TR/cssom-1/. Спецификация HTML Описывает язык HTML (например, теги) и BOM (объектную модель браузера) – разные функции браузера: setTimeout , alert , location и так далее, подробнее на https://html.spec.whatwg.org. Тут берётся за основу спецификация DOM и расширяется дополнительными свойствами и методами.

Кроме того, некоторые классы описаны отдельно на https://spec.whatwg.org/.

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

Когда вам нужно будет прочитать о каком-то свойстве или методе, справочник на сайте Mozilla https://developer.mozilla.org/ru/search тоже очень хороший ресурс, хотя ничто не сравнится с чтением спецификации: она сложная и объёмная, но сделает ваши знания максимально полными.

Для поиска чего-либо обычно удобно использовать интернет-поиск со словами «WHATWG [термин]» или «MDN [термин]», например https://google.com?q=whatwg+localstorage, https://google.com?q=mdn+localstorage.

А теперь давайте перейдём к изучению DOM, так как страница – это основа всего.

Модель объектов javascript объекты navigator’а

В модели JavaScript самым старшим объектом является объект window — считается, что все происходящее с документом вложено в окно. У окна имеется несколько объектов-свойств: location, history, document, navigator. Это не полный перечень объектов окна, но для иллюстрации модели данных JavaScript он достаточен.

Объект location ассоциируется с полем location браузера, где отображается URL загруженного в окно документа. У location есть свойства и методы. При изменении значения свойства location или при вызове метода происходит перезагрузка документа. При перезагрузке может пополняться защищенный массив объекта history — множество URL, которые посещал пользователь. Основным способом использование history являются методы window.history.back(), window.history.forward() и window.history.go(-1).

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

Если необходимо проверить исполняемость Java-кода на стороне браузера, например, для загрузки страницы с апплетом или без него, то это можно сделать, применив соответствующий метод объекта navigator.

Объект document ассоциирован с телом документа и включает в себя другие объекты, которые могут быть поименованы, как, например, объекты IMG или FORM, а также могут входить во встроенный массив, как, например, гипертекстовые ссылки (links[] ).

Первоначально в JavaScript особое внимание уделялось формам. По этой причине к формам относится наибольшее число классов объектов документа. Это и сама форма объект FORM, и элементы формы: поля ввода (input) различных типов, меню (select) и его составляющие (options), поля ввода больших блоков текста (textarea). У каждого из этих объектов достаточно большое количество свойств и методов.

Наибольших визуальных эффектов достигают за счет изменения свойства src объекта IMG, который может быть поименованным объектом документа. Он также входит во встроенный массив document.images[].

В JavaScript можно изменять значения гипертекстовых ссылок, а также указывать JavaScript-код вместо гипертекстовой ссылки, используя схему URL javascript. Это позволяет, в частности, отказаться от кнопок в формах и отправлять данные формы, нажимая на гипертекстовую ссылку.

Таким образом, видно, что модель данных JavaScript — это дерево. К его объектам принято обращаться по составным именам, например: window.document.cookie — строка ассоциативный массив «волшебных ключиков», window.document.forms.length — число форм в документе, window.document.images[0].src — URL первой картинки документа, window.location.href — URL загруженного в данный момент документа, window.frames.length — число фреймов в документе.

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

Особенность модели событий в JavaScript заключается в том, что события жестко привязаны к объекту. Например, у гипертекстовой ссылки у элемента . может быть событие onMouseover, а у элемента IMG такого события, а, следовательно, и обработчика этого события, быть не может. Логика в этом есть: IMG — это пассивный объект. В него никто не будет тыкать курсором мыши и по умолчанию при проходе курсора над IMG информация на экране не меняется. У пассивного объекта нет функций обработчиков событий, которые можно было бы заменить JavaScript-кодом. Другое дело гипертекстовая ссылка. При проходе курсора мыши над ней в строке статуса отображается URL, при выборе мышью ссылки происходит переход на другую страницу — по крайней мере, три стандартных обработчика событий у гипертекстовой ссылки имеется.

Кстати сказать, для свойств объектов в модели JavaScript определены свои правила инициализации. Например, размер картинки, если он только не указан явно в элементе разметки IMG, будет определяться первой картинкой. Все остальные картинки будут масштабироваться в этот размер независимо от их реальных линейных размеров. Аналогичное «поведение» характерно и для кнопок. Их размер определяется первой надписью, значение атрибута value элемента разметки INPUT. Это сделано для того, чтобы не переформатировать загруженный документ.

С точки зрения традиционного программирования наличие стандартных обработчиков событий и возможность изменения свойств — это вопрос инициализации данных и резервирования места под код и значения переменных. В JavaScript он решается в момент загрузки документа, когда создаются все встроенные объекты документа. После того, как произошло событие Load (обработчик onLoad элемента разметки BODY), встроенные объекты больше не создаются. По этой же причине при использовании метода document.write() после события Load приходится переписывать содержание загруженной страницы. Структура встроенных объектов страницы после ее загрузки не может быть изменена. Фактически модель данных JavaScript опирается на неизменный шаблон, который задается HTML-разметкой. Программист может только манипулировать свойствами объектов в рамках этого шаблона. Сами объекты при этом разделены на активные и пассивные, в зависимости от наличия у них обработчиков событий.

Начало создания курса: Mondy, 19-Aug-1996 10:12:15 NOVST
Дата последней модификации: Tuesday, 16-May-2000 20:40:48 NOVST
© 1996 — 2001, А.М.Федотов
© 1996 — 2001, Институт вычислительных технологий СО РАН, Новосибирск

лабы по информатике, егэ

лабораторные работы и задачи по программированию и информатике, егэ по информатике

JavaScript урок 6. Javascript объекты

JavaScript объекты

  • встроенные объекты
  • объекты браузера
  • объекты, которые программист создает самостоятельно (пользовательские)

Встроенные объекты — это предопределенные объекты number , string , array … Большинство из которых уже были рассмотрены в предыдущих уроках.

Об объектах браузера в javaScript речь пойдет в дальнейших уроках.

А сейчас время познакомиться с пользовательскими объектами в javaScript.

  • Object(объекты)
  • Number (обработка чисел)
  • String (обработка строк)
  • Array (массивы)
  • Math (математические формулы, функции и константы)
  • Date (работа с датами и временем)
  • RegExp
  • Global (его свойства Infinity, NaN, undefined)
  • Function

JavaScript создание объектов

  1. Использование инициализатора объекта (или создание объектов-коллекций)
  2. Использование конструктора объектов (создание классов-конструкторов)

var имя_объекта = new Object(); имя_объекта.свойство = значение;// точечная нотация имя_объекта[«свойство»] = значение;// скобочная нотация

Глава 11
Использование Объектов Navigator’а

В этой главе рассматриваются объекты JavaScript в Navigator’е и объясняется, как их использовать. Объекты клиентского JavaScript иногда называются объектами Navigator’а, чтобы отличить их от серверных или пользовательских объектов.

В главе имеются следующие разделы:

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

Рисунок 11.1 Иерархия объектов Navigator’а

В данной иерархии «потомки» объектов являются их свойствами. Например, форма form1 является объектом, а также свойством объекта document , и к ней обращаются document.form1 .

Список всех объектов, их свойств, методов и обработчиков событий см. в книге Клиентский JavaScript. Справочник .

На каждой странице имеются следующие объекты:

  • navigator : имеет свойства — имя и версию используемого Navigator’а, MIME-типы, поддерживаемые клиентом и plug-in’ы, установленные на клиенте.
  • window : объект верхнего уровня/top-level; имеет свойства, которые применяются ко всему окну. Каждое «дочернее окно» в документе с фрэймами также является window -объектом.
  • document : имеет свойства на основе содержимого документа, такого как заголовок, цвет фона, гиперссылки и формы.
  • location : имеет свойства на основе текущего URL.
  • history : имеет свойства, представляющие URL’ы, которые клиент запрашивал ранее.

В зависимости от содержимого, документ может содержать и другие объекты. Например, каждая форма (определённая тэгом FORM ) в документе имеет соответствующий объект Form .

Для обращения к конкретным свойствам Вы обязаны специфицировать имена объекта и всех его предков. Обычно объект получает имя в атрибуте NAME соответствующего HTML-тэга. Дополнительную информацию и пример см. в Главе 12 «Использование Окон и Фрэймов» .

Например, следующий код обращается к свойству value текстового поля text1 на форме myform в текущем документе:

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

Следующий код обращается к изображению, которое не находится на форме:

Свойства объекта document зависят от содержимого. То есть они создаются на основе HTML документа. Например, document имеет свойства для каждой формы и каждого якоря /anchor документа.

Предположим, Вы создаёте страницу simple.html , которая содержит следующий HTML:

На основе этого HTML базовые объекты могут иметь свойства вроде тех, которые показаны в таблице.

Таблица 11.1 Пример значений свойств объектов

Свойство Значение

Обратите внимание, что значение свойства document.title отражает значение, специфицированное тэгом TITLE . Значения свойств document.fgColor (цвет текста) и document.bgColor (цвет фона) не были установлены в HTML, поэтому они базируются на значениях по умолчанию, специфицированных в диалоговом окне Preferences (в меню Edit Navigator’а).

Поскольку в документе имеется форма, имеется также объект Form под названием myform (на основе атрибута NAME формы), который имеет дочерние объекты для checkbox и для button. Каждый из этих объектов имеет имя на основе атрибута NAME тэга HTML, определяющего этот объект:

  • document.myform — форма
  • document.myform.Check1 — checkbox/переключатель
  • document.myform.button1 — button/кнопка

Form -объект myform имеет другие свойства на основе атрибутов тэга FORM , например,

  • action это http://www.royalairways.com/samples/mycgi.cgi — URL по которому форма отправляется.
  • method это «get» — на основе значения атрибута METHOD .
  • length равен 3, поскольку на форме размещены три элемента.

Объект Form имеет дочерние объекты button1 и text1 , соответствующие кнопке и текстовому полю на форме. Эти объекты имеют свои собственные свойства на основе значений своих HTML-атрибутов, например,

  • button1.value имеет значение «Press Me»
  • button1.name имеет значение «Button1»
  • text1.value имеет значение «blahblah»
  • text1.name имеет значение «text1»

Вы обращаетесь к этим свойствам, используя из полное именование, например, document.myform.button1.value . Это полное имя, основанное на иерархии объектов Navigator’а, начинается с document , затем идёт имя формы, myform , затем — имя элемента, button1 , и, наконец, имя свойства.

В JavaScript значения свойств объекта основаны на содержимом Вашего HTML-документа, что иногда называется reflection/отражением , поскольку значения свойств отражают HTML. Для понимания отражения JavaScript важно разобраться, как Navigator выполняет layout\вывод — процесс трансформации Navigator’ом HTML-тэгов в графическое отображение на экране Вашего компьютера.

Обычно отображение выполняется в Navigator’е последовательно: Navigator стартует от верха HTML-файла и проходит до конца документа (вниз), отображая вывод на экране по мере прохождения документа. Из-за такого выполнения «сверху вниз», JavaScript отражает только HTML, который обнаружен. Например, Вы определяете форму и два элемента для ввода текста:

Это простой пример обновления элемента формы после завершения вывода документа.

Используя обработчики событий, Вы можете также изменять некоторые другие свойства после завершения вывода документа, такие как document.bgColor .

В этом разделе рассмотрены некоторые наиболее используемые объекты Navigator’а: window , Frame , document , Form , location , history и navigator . Дополнительно об этих объектах см. книгу Клиентский JavaScript. Справочник .

Объекты window и Frame

Объект window является «родительским» объектом для всех объектов в Navigator’е. Вы можете создать несколько окон в приложении JavaScript. Объект Frame определяется тэгом FRAME в документе FRAMESET . Frame -объекты имеют те же свойства и методы, что и объекты window , и отличаются только способом отображения.

Объект window имеет несколько широко используемых методов, в том числе:

  • open и close : открывают и закрывают окно браузера; Вы можете специфицировать размер окна, его содержимое и наличие панели кнопок/button bar, адресной строки/location field и других «chrome»-атрибутов.
  • alert — Выводит диалоговое окно Alert с сообщением.
  • confirm — Выводит диалоговое окно Confirm с кнопками OK и Cancel.
  • prompt — Выводит диалоговое окно Prompt с текстовым полем для ввода значения.
  • blur и focus — Убирают и передают фокус окну.
  • scrollTo — Прокручивает окно на специфицированные координаты.
  • setInterval — Вычисляет выражение или вызывает функцию многократно по истечении специфицированного периода времени.
  • setTimeout — Вычисляет выражение или вызывает функцию однократно по истечении специфицированного периода времени.

window имеет также несколько свойств, которые могут устанавливаются Вами, таких как location и status .

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

Свойство status можно использовать для показа сообщения в статусной строке/status bar внизу клиентского окна; дополнительно см. «Использование Статусной Строки» .

Об окнах и фрэймах см. дополнительно Главу 12 «Использование Окон и Фрэймов» . В данной книге не рассматривается полный набор методов и свойств объекта window . Полный список см. в книге Клиентский JavaScript. Справочник .

Объект document

Каждая страница имеет единственный объект document .

Поскольку его методы write и writeln генерируют HTML, объект document является одним из наиболее используемых объектов Navigator’а. О методах write и writeln см. раздел «Использование Метода write» .

Объект document имеет несколько свойств, отражающих цвет фона, текста и гиперссылок страницы: bgColor , fgColor , linkColor , alinkColor и vlinkColor . Часто используются lastModified , дата последнего изменения страницы, referrer , предыдущий URL, посещённый клиентом, и URL , URL документа. Свойство cookie даёт возможность устанавливать и получать значения кук; см. также «Использование Кук» .

Объект document является предком всех объектов Anchor , Applet , Area , Form , Image , Layer , Link и Plugin страницы.

Пользователи могут печатать и сохранять сгенерированный HTML, используя команды меню File Navigator’а (JavaScript 1.1 и позднее).

Объект Form

Каждая форма документа создаёт объект Form . Поскольку в документе может быть не одна форма, Form -объекты хранятся в массиве forms . Первая форма (самая верхняя на странице) это forms[0] , вторая — forms[1] , и так далее. Помимо обращения к форме по имени, Вы можете обратиться к первой (например) форме так:

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

Каждый элемент формы имеет свойство form , которое является ссылкой на родительскую форму элемента. Это свойство используется в основном в обработчиках событий, где может понадобиться обратиться к другому элементу на текущей форме. В следующем примере форма myForm содержит Text -объект и кнопку. Если пользователь щёлкает по кнопке, значением Text -объекта становится имя формы. Обработчик onClick кнопки использует this.form для обращения к родительской форме, myForm .

Объект location

Объект location имеет свойства на основе текущего URL. Например, свойство hostname это сервер и имя домена сервера — хоста текущего документа.

Объект location имеет два метода:

  • reload — форсирует перезагрузку текущего документа окна.
  • replace — загружает специфицированный URL поверх текущего вхождения списка history.

Объект history

Объект history содержит список строк, представляющих URL’ы, посещённые клиентом. Вы можете получить текущее, предыдущее и следующее вхождение из history через использование свойств current , next и previous объекта history . Вы получить доступ к другим значениям в history, используя массив history . Этот массив содержит вхождение для каждого вхождения history в порядке исходного кода; каждое вхождение массива это строка, содержащая URL.

Можно также перенаправить клиент к любому вхождению списка history методом go . Например, следующий код загружает URL, находящийся на две позиции назад в списке history клиента.

Следующий код перезагружает текущую страницу:

Список history отображается в меню Go Navigator’а.

Объект navigator

Объект navigator содержит информацию о версии используемого Navigator’а. Например, свойство appName специфицирует имя браузера, а свойство appVersion специфицирует версию Navigator’а.

Объект navigator имеет три метода:

  • javaEnabled специфицирует, включен ли Java
  • preference позволяет использовать маркированный скрипт для получения различных пользовательских настроек (JavaScript 1.2 и позднее)
  • taintEnabled специфицирует, включено ли разрушение данных/tainting (только JavaScript 1.1)

Некоторые объекты Navigator’а имеют свойства, значения которых являются массивами. Эти массивы используются для хранения информации, когда Вы заранее не знаете, сколько будет значений. В таблице показано, какие свойства каких объектов имеют массивы в качестве значений.

Таблица 11.2 Предопределённые массивы JavaScript

Объект Свойство Описание

Отражает тэги в порядке расположения в исходном коде.

Отражает тэги в порядке расположения в исходном коде.

Отражает тэги в порядке расположения в исходном коде (изображения, созданные конструктором Image() , не включаются в массив images ).

Отражает тэги и в порядке расположения в исходном коде.

Отражает элементы формы (такие как объекты Checkbox , Radio и Text ) в порядке расположения в исходном коде.

Отражает аргументы функции.

Отражает все MIME-типы, поддерживаемые клиентом (внутренне, через вспомогательные приложения или через plug-in’ы).

Отражает все plug-in’ы, установленные на клиенте, в порядке расположения в исходном коде.

Отражает опции объекта Select (тэги ) в порядке расположения в исходном коде.

Отражает все тэги в окне, содержащем тэг , в порядке расположения в исходном коде.

Отражает вхождения history окна.

Вы можете индексировать порядковыми числами или по именам (если определены). Например, если второй тэг имеет в атрибуте NAME значение «myForm», Вы можете обратиться к форме document.forms[1] , или document.forms[«myForm»] или document.myForm .

Например, определён следующий элемент:

Если Вы хотите обратиться к этому элементу формы по имени, можно специфицировать document.forms[«Comments»] .

Все предопределённые массивы JavaScript имеют свойство length, которое указывает количество элементов массива. Например, чтобы получить количество форм в документе, используйте свойство length : document.forms.length .

JavaScript 1.0. Вы обязаны индексировать массивы порядковыми числами, например document.forms[0] .

Метод write объекта document отображает вывод в Navigator’е. «Зачем?», спросите Вы, «ведь это уже делает HTML». Но в скрипте можно сделать то, чего не может обычный HTML. Например, Вы можете вывести текст на основе выполнения условия или аргументов переменной. Поэтому write это один из наиболее часто используемых методов JavaScript.

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

Вот скрипт, генерирующий динамический HTML с помощью JavaScript:

В HEAD этого документа определены две функции:

  • bar , которая отображает горизонтальную линию HTML, имеющую ширину, специфицированную аргументом функции.
  • output , которая отображает заголовок HTML того уровня, который специфицирован первым аргументом, и текст параграфа, специфицированный третьим аргументом.

Затем в тэге BODY документа эти две функции вызываются и дают на выходе:

Рисунок 11.2 Вывод, созданный с использованием функций JavaScript

Следующая строка создаёт вывод функции bar :

Заметьте, что в определении bar использованы знаки одинарных кавычек вместо двойных. Вы обязаны делать так при обозначении закавыченной строки внутри строкового литерала. Затем вызов bar с аргументом 25 производит вывод, эквивалентный следующему HTML:

write сопутствующий метод writeln , который добавляет последовательность символов «новая строка» (возврат каретки или возврат каретки + прогон строки, в зависимости от платформы) в конец своего вывода. Поскольку HTML обычно игнорирует символы новой строки, разницы между write и writeln нет, за исключением положения внутри таких тэгов, как PRE .

Печать вывода

Navigator версии 3.0 печатает вывод, созданный в JavaScript. Для распечатки вывода, пользователь выбирает Print из меню File Navigator’а. Navigator 2.0 не распечатывает вывод, создаваемый JavaScript.

Если Вы распечатываете страницу, содержащую слои/layers (Navigator 4.0 и позднее), каждый слой печатается отдельно на той же странице. Например, если три слоя перекрывают друг друга в браузере, распечатанная страница показывает каждый слой отдельно.

Если Вы выбрали Page Source из меню View Navigator’а или View Frame Source из контекстного меню (правой клавишей мыши), web-браузер отображает содержимое HTML-файла со сгенерированным HTML. Если Вы хотите просмотреть исходный HTML со скриптами генерирующими HTML (с методами document.write и document.writeln ), не используйте меню Page Source и View Frame Source. Тогда используйте протокол view-source: . Например, предположим, файл file://c|/test.html содержит такой текст:

При загрузке этого URL браузер выведет:

Если выбрать Page Source из меню View, браузер выведет:

Если загрузить view-source:file://c|/test.html , браузер выведет:

Отображение вывода

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

Оглавление | Назад | Вперёд | Индекс

Дата последнего обновления: 25 мая 1999 года.
Copyright (c) 1999 Netscape Communications Corporation

Объекты navigator, screen и location — Информация о браузере и разрешении экрана — Текущий URL

Урок №8 Объекты navigator, screen и location

Количество просмотров : 908

Здесь будут рассмотрены несколько объектов — это navigator , screen и location .

Все эти объекты является дочерними по отношению к глобальному объекту Window .

Доступ к ним осуществляется как к свойствам объекта Window , то есть через точку .

Объект navigator — информация о браузере и о ОС

Объект navigator содержит информацию о браузере пользователя (в частности — доступно ли использование cookie файлов и включена ли поддержка Java).

Также объект navigator позволяет определить тип операционной системы.

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

Далее, при помощи свойств объекта navigator получим и выведем на экран следующие данные:

— информацию о браузере — свойство userAgent ;

— язык браузера — свойство language ;

— название операционной системы — свойство oscpu ;

— включены ли куки — свойство cookieEnable d;

— подключен ли пользователь к сети Интернет — свойство onLine .

Доступ к свойствам объекта navigator осуществляется через точку.

Объект screen — Разрешение экрана пользователя

Объект screen поможет получить данные о разрешении экрана пользователя, о глубине цвета и др.

С объектом screen поступим аналогично: сначала выведем на экран все его свойства.

Теперь при помощи свойств height и width объекта screen получим информацию: о разрешении экрана — его высоте и ширине в пикселях. А также о битовой глубине цветовой палитры — свойство colorDepth .

Объект location — текущий URL-адрес

Объект location возвращает URL-адрес текущего окна пользователя.

А также содержит данные о частях и компонентах текущего адреса: имя хоста, номер порта, протокол и т.д.

Свойства объекта location .

Воспользуемся свойством href объекта location , чтобы вывести на экран URL-адрес текущего документа.

Домашнее задание

Выполним домашнее задание по этому уроку.

Выясните, с какого браузера человек зашел на вашу страничку и, в зависимости от браузера, выведите на экран:

Если firefox: «Ваш браузер Firefox.»
Если opera: «Ваш браузер Opera.»
Если chrome: «Ваш браузер Chrome.»

Для решения этого домашнего задания нужно :

При помощи свойства userAgent объекта navigator получить информацию о текущем браузере.


На момент решения этой задачи я получил следующие данные о браузерах Firefox , Opera и Chrome .

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox /56.0

Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /61.0.3163.100 Safari/537.36 OPR /48.0.2685.39

Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /61.0.3163.100 Safari/537.36

При помощи регулярных выражений найти названия браузеров из информации о них .

См. также уроки о регулярных выражениях в теме «Свойства и методы строковых объектов».

При помощи метода match вернуть совпадения и составить условия if-else.

Обратите внимание : название Chrome присутствует не только в описании браузера Chrome , но и в данных о браузере Opera .
Этот момент нужно будет учесть при составлении условий.

Следует также напомнить : если метод match не находит совпадений, то он возвращает null.

Работа с объектами в JavaScript: теория и практика

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

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

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

Объекты в JavaScript

Во многих статьях встречается фраза «В JavaScript — всё объект». Технически это не совсем верно, однако производит должное впечатление на новичков :)

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

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

Итак, в JavaScript есть 6 базовых типов данных — это Undefined (обозначающий отсутствие значения), Null, Boolean (булев тип), String (строка), Number (число) и Object (объект).
При этом первые 5 являются примитивными типами данных, а Object — нет. Кроме того, условно можно считать, что у типа Object есть «подтипы»: массив (Array), функция (Function), регулярное выражение (RegExp) и другие.
Это несколько упрощенное описание, но на практике обычно достаточное.

Кроме того, примитивные типы String, Number и Boolean определенным образом связаны с не-примитивными «подтипами» Object: String, Number и Boolean соответственно.
Это означает, что строку ‘Hello, world’, например, можно создать и как примитивное значение, и как объект типа String.
Если вкратце, то это сделано для того, чтобы программист мог и в работе с примитивными значениями использовать методы и свойства, как будто это объекты. А подробнее об этом можно будет прочитать в соответствующем разделе данной статьи.

Работа по ссылке

Ссылка — это средство доступа к объекту под различными именами. Работа с любыми объектами ведется исключительно по ссылке.
Продемонстрируем это на примере:

test= function () //Создадим функцию (а функция, как мы помним, является полноправным объектом) и сделаем переменную test ссылкой на нее
test_link=test; //test_link теперь тоже ссылается на нашу функцию
test(); //Hello!
test_link(); //Hello!
* This source code was highlighted with Source Code Highlighter .

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

Наша функция, как и любой другой объект — просто область в памяти, и все ссылки на эту область абсолютно равнозначны. Более того, объект может вообще не иметь ссылок — в таком случае он называется анонимным, и может быть использован только непосредственно сразу после создания (например, передан в функцию), иначе доступ к нему получить будет невозможно и в скором времени он будет уничтожен сборщиком мусора (garbage collection), который и занимается тем, что удаляет объекты без ссылок.

Посмотрим, почему так важно это понимать:

test= //Создаем объект со свойством prop
test_link=test; //Создаем еще одну ссылку на этот объект

alert(test.prop); //sometext
alert(test_link.prop); //sometext

//Изменяем свойство объекта
test_link.prop= ‘newtext’ ;

alert(test.prop); //newtext
alert(test_link.prop); //newtext
/*Можно было бы сказать, что свойство изменилось и там и тут — но это не так.
Объект-то один. Так что свойство изменилось в нем один раз, а ссылки просто продолжают указывать туда, куда и указывают. */

//Добавляем новое свойство и удаляем старое
test.new_prop= ‘hello’ ;
delete test.prop;

alert(test_link.prop); //undefined — такого свойства больше нет
alert(test_link.new_prop); //hello — что и следовало ожидать

//Удаляем ссылку
delete test;
alert(test.new_prop);
/*В этом месте скрипт выкинет ошибку, потому что test уже не существует, и test.new_prop не существует тем более */
alert(test_link.new_prop); //hello
/* а вот тут все в порядке, ведь мы удалили не сам объект, а лишь ссылку на него. Теперь на наш объект указывает единственная ссылка test_link */

//Создаем новый объект
test=test_link; //Сперва снова создадим ссылку test
test_link= //А вот и новый объект

alert(test_link.prop); //sometext
alert(test.prop); //undefined
/* Cоздание нового объекта разрывает ссылочную связь, и теперь test и test_link указывают на разные объекты.
Фактически, это равносильно удалению ссылки test_link и созданию ее заново, но уже указывающей на другой объект */
alert(test.new_prop); //hello — теперь test содержит ссылку на наш самый первый объект

* This source code was highlighted with Source Code Highlighter .

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

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

Примитивные значения

obj= new String( ‘hello’ ); //Создаем строку как объект
simple= ‘hello’ ; //Создаем примитивное значение

alert(obj); //hello
alert(simple); //hello — пока все предсказуемо

alert(obj.length); //6 — у объекта типа String есть свойство length, хранящее длину строки
alert(simple.length); //6
/* Хотя simple — не объект, мы можем обращаться к тому же набору свойств, что и у объекта типа String. Это довольно удобно */

obj.prop= ‘text’ ;
simple.prop= ‘text’ ;

alert(obj.prop); //text — раз obj обычный объект, то мы можем запросто придать ему еще одно свойство
alert(simple.prop); //undefined — а вот simple не объект, и этот номер у нас не пройдет

* This source code was highlighted with Source Code Highlighter .

Все то же самое справедливо и для типа Number, и для Boolean (ну, кроме того, что в них нет свойства length, а есть ряд других замечательных свойств).
Использование строк и чисел как объектов не несет в себе никакой практической пользы, т.к. примитивные значения удобнее в работе, но сохраняют при этом весь необходимый функционал. Тем не менее, для полноты картины необходимо понимать этот механизм.

Не стоит путать использование примитивных значений с использованием литералов — например, независимо от того, создаем мы массив как «test=new Array()» или как «test=[]», в результате все равно будет один и тот же объект. Никаких примитивных значений мы не получим.

Создание и использование объектов

test= <
simple_property: ‘Hello’ ,
object_property: <
user_1: ‘Петя’ ,
user_2: ‘Вася’
>,
function_property: function (user) <
alert( this .simple_property + ‘, ‘ + this .object_property[user]);
>
>

test.function_property( ‘user_1’ ); //Hello, Петя.

* This source code was highlighted with Source Code Highlighter .

Перед нами объект test, имеющий 3 свойства, названия которых, как я надеюсь, говорят сами за себя. Больше всего нас в нем интересует свойство function_property, содержащее функцию. Такую функцию можно назвать методом объекта.

В нашей функции дважды используется ключевое слово this, которое является указателем (т.е. ссылкой) на объект, из которого вызывается функция. Таким образом, this.simple_property=test.simple_property=’Hello’, а this.object_property[user]=test.object_property[user]=’Петя’.

Необходимо четко осознавать, this всегда указывает именно на объект, из которого вызвана функция, а не на объект, к которому она принадлежит. Хотя в данном примере это один и тот же объект, это не всегда так.

test.function_property( ‘user_1’ ); //Hello, Петя.

test2= new Object(); //Еще одна форма создания нового объекта, аналогичная test2=<>

test.function_property.call(test2, ‘user_1’ ); //ошибка
/* Метод call позволяет вызвать функцию от имени другого объекта. В данном случае, мы вызываем метод function_property объекта test, и его this указывает уже не на объект test, а на объект test2. А т.к. в нем нет свойства object_property, то при попытке получить this.object_property[user]скрипт выдаст ошибку */

//попробуем исправить ситуацию
test2.simple_property= ‘Good day’ ;
test2.object_property=test.object_property; //В данном случае воспользуемся указанием объекта по ссылке, чтобы не дублировать код

test.function_property.call(test2, ‘user_1’ ); //Good day, Петя.

* This source code was highlighted with Source Code Highlighter .

Из примера также должно быть видно, что нет четких этапов создания и использования объекта. Объект может быть как угодно модифицирован в любое время — до, после и даже во время использования. Это тоже важное отличие от «традиционного» ООП.

Конструктор

В примере выше мы создавали 2 объекта, обладающих некой схожестью. И там и там имелись свойства simple_property и object_property. Очевидно, что при написании реального кода также нередко встает задача создания одинаковых или просто похожих объектов. И разумеется, мы не должны каждый такой объект создавать вручную.

На помощь нам придет конструктор. Конструктор в JavaScript — это не часть класса (потому что здесь нет классов), а просто самостоятельная функция. Самая обычная функция.

make_me= function (_name) <
alert( ‘меня запустили’ );
this .name=_name;
this .show_name= function ()
>

child= new make_me( ‘Вася’ ); //меня запустили
/* Давайте разберемся, что здесь происходит. Интерпретатор видит оператор new и проверяет, что находится справа от него. Т.к. make_me — это функция, и она может быть использована в качестве контруктора, то создается новый объект в памяти и запускается на выполнение функция make_me, причем ее this указывает как раз на этот новый объект. Далее этому объекту добавляется свойство name, которому присваивается значение из аргумента _name, и метод show_name. Также (не знаю в какой именно момент, но это и не важно) переменная child начинает указывать на наш новенький, только что рожденный объект */

alert(child.name); //Вася
child.show_name(); //Вася

child2= new make_me( ‘Петя’ );
child2.show_name(); //Петя

child2.show_name= function () //Не забываем, что можем изменять наши объекты в любой момент
child2.show_name(); //Не буду говорить свое имя

child.show_name(); //Вася — дети никак не влияют друг на друга

* This source code was highlighted with Source Code Highlighter .

Если мы вспомним про описание типов данных в начале статьи, то становится понятно, что Object и его подтипы (Function, Array и другие) — это на самом деле конструкторы, придающие создаваемому объекту возможности функции, массива и т.д.

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

Прототип

make_me= function (_name) <
alert( ‘меня запустили’ );
this .name=_name;
this .show_name= function ()
>
/*
Видя ключевое слово function, интерпретатор проверяет код справа от него, и т.к. все ок — создает новый объект в памяти, который одновременно является нашей функцией. Затем, автоматически (без участия программиста) для этой функции создается свойство prototype, ссылающееся на пустой объект. Если бы мы это делали вручную, это выглядело бы как make_me.prototype=new Object();

Затем, данному объекту (на который указывает свойство prototype) также автоматически добавляется свойство constructor, указывающее обратно на функцию. Получается такая вот циклическая ссылка.

Теперь этот объект, который можно описать как — и есть прототип функции.
*/

alert( typeof make_me.prototype); //Object — действительно, объект
alert( typeof make_me.prototype.constructor); //Function — это наша функция
alert(make_me.prototype.constructor === make_me); //true

make_me.prototype.set_name= function (_name) < this .name=_name;>//Добавляем в прототип функции make_me новый метод

child= new make_me( ‘Вася’ ); //меня запустили
/* Теперь помимо всего того, что описано в предыдущем примере, дополнительно в объекте child создается скрытое свойство [[Prototype]], которое указывает на тот же объект, что и make_me.prototype. Т.к. свойство скрыто, мы не можем ни просмотреть его значение, ни изменить его — однако оно играет важную роль в дальнейшей работе */

alert(child.name); //Вася
child.show_name(); //Вася

child.set_name( ‘Коля’ );
/* Сначала, интерпретатор ищет метод set_name в объекте child. Так как его там нет, он продолжает поиск в свойстве child.[[Prototype]], находит его там и запускает. */
child.show_name(); //Коля — теперь Васю зовут Коля :)

make_me.prototype.show_name2= function () //Т.к. прототип — это обычный объект, мы точно также можем его менять на лету

child2= new make_me( ‘Петя’ );
child2.show_name2(); //Привет, Петя
child.show_name2(); //Привет, Коля — изменения в прототипе влияют не только на вновь созданные объекты, но и на все старые

child2.show_name2= function () //Мы по прежнему можем изменить сам объект, при этом новый метод show_name2 в данном объекте (и только в нем) как бы «затрет» старый метод из прототипа
child2.show_name2(); //Не буду говорить свое имя — т.к. у нас теперь есть собственный метод show_name2, то он и вызывается, и поиск в прототипе не происходит

child.show_name2(); //Привет, Коля — здесь все по прежнему

make_me.prototype= //Попробуем пересоздать прототип заново

alert(child.prop); //undefined
child.show_name2(); //Привет, Коля
/* Если вспомнить, что такое работа по ссылке, то все понятно. Пересоздание прототипа рвет связь, и теперь свойство [[Prototype]] у объектов child и child2 указывают на один объект (который раньше был прототипом функции make_me), а свойство make_me.prototype — на другой объект, который является новым прототипом функции make_me */

child3= new make_me( ‘Олег’ );
alert(child3.prop); //hello — что и следовало ожидать

* This source code was highlighted with Source Code Highlighter .

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

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

make_me= function (_name) <
alert( ‘меня запустили’ );
this .name=_name;
this .show_name= function ()
>

make_me.prototype.set_name= function (_name) < this .name=_name;>
child= new make_me( ‘Вася’ );

alert( typeof make_me.prototype); //object — у функции есть свойство prototype
alert( typeof child.prototype); //undefined — у созданного объекта НЕТ свойства prototype
alert(child.constructor.prototype === make_me.prototype); //true — зато у объекта есть свойство constructor, которое указывает на функцию-конструктор make_me, у которой, в свою очередь, есть свойство prototype

* This source code was highlighted with Source Code Highlighter .

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

Необходимо всегда четко понимать, что если речь идет о прототипе конструктора — то это всегда свойство prototype, а если о прототипе созданного объекта — то это скрытое свойство [[Prototype]].

Наследование

bird= function () <> //Это конструктор птички
bird.prototype.cry= function () //Птичка умеет кричать
bird.prototype.fly= function () //и летать

duck= function () <>
duck.prototype= new bird();
duck.prototype.cry= function () //Утка кричит по другому
duck.prototype.constructor=duck; //Принудительно устанавливаем свойство prototype.constructor в duck, т.к. иначе оно будет ссылаться на bird

billy = new duck(); //Билли — это наша утка
billy.fly(); //Я лечу! — Билли может летать, потому что он птица
billy.cry(); //Кря-кря! — Билли кричит кря-кря, потому что он утка

* This source code was highlighted with Source Code Highlighter .

Так можно реализовывать иерархию любого уровня вложенности.

Задача на звездочку

make_me= function () <>
child= new make_me();
alert(child.toString()); //выводит [object]

* This source code was highlighted with Source Code Highlighter .

В первой строке мы создаем новую функцию и переменную make_me, которая указывает на эту функцию. При этом создается прототип функции, make_me.prototype, в котором содержится свойство constructor, указывающее на make_me.
Но это далеко не все :)
Т.к. функция make_me — это тоже объект, то он в свою очередь имеет папу и маму, т.е. конструктор и прототип. Его конструктор — это родная функция языка Function(), а прототип — объект, содержащий в себе методы call, apply и т.д. — именно благодаря этому прототипу мы и можем пользоваться этими методами в любой функции. Таким образом, у функции make_me появляется свойство [[Prototype]], указывающее на Function.prototype.

В свою очередь, прототип конструктора Function — тоже объект, конструктором которого является (сюрприз!) Object (т.е. Function.prototype.[[Prototype]].constructor===Object), а прототипом — объект, содержащий стандартные свойства и методы объекта, такие как toString, hasOwnProperty и другие (другими словами — Function.prototype.[[Prototype]][‘hasOwnProperty’] — это как раз тот самый метод, которым мы можем пользоваться во всех производных объектах — причем это именно собственной метод данного объекта, а не наследованный). Вот таким вот интересным образом мы обнаруживаем, что все виды объектов являются производными от Object.

Можем ли мы продолжить дальше? Оказывается, нет. Object.prototype именно потому и содержит базовые свойства объекта, что не имеет собственного прототипа. Object.prototype.[[Prototype]]=null; В этом месте путешествие по цепочке прототипов в поиске свойства или метода прекращается.

Еще один интересный факт — конструктором Object является Function. Т.е. Object.[[Prototype]].constructor===Function.
Налицо еще одна циклическая ссылка — конструктор Object это Function, а конструктор Function.prototype — это Object.

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

Ну и в третей строчке мы видим, как интепретатор поднимается по цепочке, от child к child.[[Prototype]] (он же make_me.prototype), затем к child.[[Prototype]].[[Prototype]] (он же Object.prototype), и уже там находит метод toString, который и запускает на выполнение.

Примеси

Может показаться, что наследование через прототипы — единственный способ, возможный в JavaScript. Это не так.
Мы имеем дело с очень гибким языком, который предоставляет не столько правила, сколько возможности.

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

//Это конструктор человека
man= function () <
this .live= function () //Человек умеет жить
this .walk= function () //Человек умеет ходить
>

//Это конструктор поэта
poet= function () <
this .kill= function () //Поэт может убить человека
this .live= function () //От этого человек умрет
>

vladimir= new man(); //Владимир — человек
vladimir.live(); //Я живу — он жив
vladimir.walk(); //Я иду — он ходит

poet.call(vladimir); //Выполняем конструктор poet для объекта vladimir
vladimir.kill(); //Поэт убил человека
vladimir.live(); //Я мертв

//А теперь фокус
man.call(vladimir);
vladimir.live(); //Я живу

* This source code was highlighted with Source Code Highlighter .

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

Upd: Замыкания и приватные свойства

Чтобы не раздувать эту и без того немаленькую статью, даю ссылку на пост Замыкания в JavaScript, где про это довольно подробно написано.

Что теперь со всем этим делать

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

Причем вопрос о цене довольно нетривиален, особенно если мы говорим о разработке под браузер Internet Explorer 6 и 7 версий.
1. Память — тут все просто. Во всех браузерах наследование на прототипах отнимает в разы меньше памяти, чем при создании методов через конструкторы. Причем, чем больше методов и свойств у нас есть, тем больше разница. Однако, стоит помнить, что если у нас не тысяча одинаковых объектов а всего лишь один, то расходы памяти в любом случае будут небольшими, т.к. здесь стоит учитывать другие факторы.
2. Процессорное время — здесь основные тонкости связанны именно с браузерами от Microsoft.
С одной стороны, объекты, где методы и свойства создаются через конструктор — могут создаваться в разы (в некоторых случаях в десятки и сотни раз) медленнее, чем через прототип. Чем больше методов — тем медленнее. Так что если у вас в IE замирает на несколько секунд во время инициализации скрипта — есть повод копать в эту сторону.

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

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

Глава 11
Использование Объектов Navigator’а

В этой главе рассматриваются объекты JavaScript в Navigator’е и объясняется, как их использовать. Объекты клиентского JavaScript иногда называются объектами Navigator’а, чтобы отличить их от серверных или пользовательских объектов.

В главе имеются следующие разделы:

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

Рисунок 11.1 Иерархия объектов Navigator’а

В данной иерархии «потомки» объектов являются их свойствами. Например, форма form1 является объектом, а также свойством объекта document , и к ней обращаются document.form1 .

Список всех объектов, их свойств, методов и обработчиков событий см. в книге Клиентский JavaScript. Справочник .

На каждой странице имеются следующие объекты:

  • navigator : имеет свойства — имя и версию используемого Navigator’а, MIME-типы, поддерживаемые клиентом и plug-in’ы, установленные на клиенте.
  • window : объект верхнего уровня/top-level; имеет свойства, которые применяются ко всему окну. Каждое «дочернее окно» в документе с фрэймами также является window -объектом.
  • document : имеет свойства на основе содержимого документа, такого как заголовок, цвет фона, гиперссылки и формы.
  • location : имеет свойства на основе текущего URL.
  • history : имеет свойства, представляющие URL’ы, которые клиент запрашивал ранее.

В зависимости от содержимого, документ может содержать и другие объекты. Например, каждая форма (определённая тэгом FORM ) в документе имеет соответствующий объект Form .

Для обращения к конкретным свойствам Вы обязаны специфицировать имена объекта и всех его предков. Обычно объект получает имя в атрибуте NAME соответствующего HTML-тэга. Дополнительную информацию и пример см. в Главе 12 «Использование Окон и Фрэймов» .

Например, следующий код обращается к свойству value текстового поля text1 на форме myform в текущем документе:

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

Следующий код обращается к изображению, которое не находится на форме:

Свойства объекта document зависят от содержимого. То есть они создаются на основе HTML документа. Например, document имеет свойства для каждой формы и каждого якоря /anchor документа.

Предположим, Вы создаёте страницу simple.html , которая содержит следующий HTML:

На основе этого HTML базовые объекты могут иметь свойства вроде тех, которые показаны в таблице.

Таблица 11.1 Пример значений свойств объектов

Свойство Значение

Обратите внимание, что значение свойства document.title отражает значение, специфицированное тэгом TITLE . Значения свойств document.fgColor (цвет текста) и document.bgColor (цвет фона) не были установлены в HTML, поэтому они базируются на значениях по умолчанию, специфицированных в диалоговом окне Preferences (в меню Edit Navigator’а).

Поскольку в документе имеется форма, имеется также объект Form под названием myform (на основе атрибута NAME формы), который имеет дочерние объекты для checkbox и для button. Каждый из этих объектов имеет имя на основе атрибута NAME тэга HTML, определяющего этот объект:

  • document.myform — форма
  • document.myform.Check1 — checkbox/переключатель
  • document.myform.button1 — button/кнопка

Form -объект myform имеет другие свойства на основе атрибутов тэга FORM , например,

  • action это http://www.royalairways.com/samples/mycgi.cgi — URL по которому форма отправляется.
  • method это «get» — на основе значения атрибута METHOD .
  • length равен 3, поскольку на форме размещены три элемента.

Объект Form имеет дочерние объекты button1 и text1 , соответствующие кнопке и текстовому полю на форме. Эти объекты имеют свои собственные свойства на основе значений своих HTML-атрибутов, например,

  • button1.value имеет значение «Press Me»
  • button1.name имеет значение «Button1»
  • text1.value имеет значение «blahblah»
  • text1.name имеет значение «text1»

Вы обращаетесь к этим свойствам, используя из полное именование, например, document.myform.button1.value . Это полное имя, основанное на иерархии объектов Navigator’а, начинается с document , затем идёт имя формы, myform , затем — имя элемента, button1 , и, наконец, имя свойства.

В JavaScript значения свойств объекта основаны на содержимом Вашего HTML-документа, что иногда называется reflection/отражением , поскольку значения свойств отражают HTML. Для понимания отражения JavaScript важно разобраться, как Navigator выполняет layout\вывод — процесс трансформации Navigator’ом HTML-тэгов в графическое отображение на экране Вашего компьютера.

Обычно отображение выполняется в Navigator’е последовательно: Navigator стартует от верха HTML-файла и проходит до конца документа (вниз), отображая вывод на экране по мере прохождения документа. Из-за такого выполнения «сверху вниз», JavaScript отражает только HTML, который обнаружен. Например, Вы определяете форму и два элемента для ввода текста:

Это простой пример обновления элемента формы после завершения вывода документа.

Используя обработчики событий, Вы можете также изменять некоторые другие свойства после завершения вывода документа, такие как document.bgColor .

В этом разделе рассмотрены некоторые наиболее используемые объекты Navigator’а: window , Frame , document , Form , location , history и navigator . Дополнительно об этих объектах см. книгу Клиентский JavaScript. Справочник .

Объекты window и Frame

Объект window является «родительским» объектом для всех объектов в Navigator’е. Вы можете создать несколько окон в приложении JavaScript. Объект Frame определяется тэгом FRAME в документе FRAMESET . Frame -объекты имеют те же свойства и методы, что и объекты window , и отличаются только способом отображения.

Объект window имеет несколько широко используемых методов, в том числе:

  • open и close : открывают и закрывают окно браузера; Вы можете специфицировать размер окна, его содержимое и наличие панели кнопок/button bar, адресной строки/location field и других «chrome»-атрибутов.
  • alert — Выводит диалоговое окно Alert с сообщением.
  • confirm — Выводит диалоговое окно Confirm с кнопками OK и Cancel.
  • prompt — Выводит диалоговое окно Prompt с текстовым полем для ввода значения.
  • blur и focus — Убирают и передают фокус окну.
  • scrollTo — Прокручивает окно на специфицированные координаты.
  • setInterval — Вычисляет выражение или вызывает функцию многократно по истечении специфицированного периода времени.
  • setTimeout — Вычисляет выражение или вызывает функцию однократно по истечении специфицированного периода времени.

window имеет также несколько свойств, которые могут устанавливаются Вами, таких как location и status .

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

Свойство status можно использовать для показа сообщения в статусной строке/status bar внизу клиентского окна; дополнительно см. «Использование Статусной Строки» .

Об окнах и фрэймах см. дополнительно Главу 12 «Использование Окон и Фрэймов» . В данной книге не рассматривается полный набор методов и свойств объекта window . Полный список см. в книге Клиентский JavaScript. Справочник .

Объект document

Каждая страница имеет единственный объект document .

Поскольку его методы write и writeln генерируют HTML, объект document является одним из наиболее используемых объектов Navigator’а. О методах write и writeln см. раздел «Использование Метода write» .

Объект document имеет несколько свойств, отражающих цвет фона, текста и гиперссылок страницы: bgColor , fgColor , linkColor , alinkColor и vlinkColor . Часто используются lastModified , дата последнего изменения страницы, referrer , предыдущий URL, посещённый клиентом, и URL , URL документа. Свойство cookie даёт возможность устанавливать и получать значения кук; см. также «Использование Кук» .

Объект document является предком всех объектов Anchor , Applet , Area , Form , Image , Layer , Link и Plugin страницы.

Пользователи могут печатать и сохранять сгенерированный HTML, используя команды меню File Navigator’а (JavaScript 1.1 и позднее).

Объект Form

Каждая форма документа создаёт объект Form . Поскольку в документе может быть не одна форма, Form -объекты хранятся в массиве forms . Первая форма (самая верхняя на странице) это forms[0] , вторая — forms[1] , и так далее. Помимо обращения к форме по имени, Вы можете обратиться к первой (например) форме так:

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

Каждый элемент формы имеет свойство form , которое является ссылкой на родительскую форму элемента. Это свойство используется в основном в обработчиках событий, где может понадобиться обратиться к другому элементу на текущей форме. В следующем примере форма myForm содержит Text -объект и кнопку. Если пользователь щёлкает по кнопке, значением Text -объекта становится имя формы. Обработчик onClick кнопки использует this.form для обращения к родительской форме, myForm .

Объект location

Объект location имеет свойства на основе текущего URL. Например, свойство hostname это сервер и имя домена сервера — хоста текущего документа.

Объект location имеет два метода:

  • reload — форсирует перезагрузку текущего документа окна.
  • replace — загружает специфицированный URL поверх текущего вхождения списка history.

Объект history

Объект history содержит список строк, представляющих URL’ы, посещённые клиентом. Вы можете получить текущее, предыдущее и следующее вхождение из history через использование свойств current , next и previous объекта history . Вы получить доступ к другим значениям в history, используя массив history . Этот массив содержит вхождение для каждого вхождения history в порядке исходного кода; каждое вхождение массива это строка, содержащая URL.

Можно также перенаправить клиент к любому вхождению списка history методом go . Например, следующий код загружает URL, находящийся на две позиции назад в списке history клиента.

Следующий код перезагружает текущую страницу:

Список history отображается в меню Go Navigator’а.

Объект navigator

Объект navigator содержит информацию о версии используемого Navigator’а. Например, свойство appName специфицирует имя браузера, а свойство appVersion специфицирует версию Navigator’а.

Объект navigator имеет три метода:

  • javaEnabled специфицирует, включен ли Java
  • preference позволяет использовать маркированный скрипт для получения различных пользовательских настроек (JavaScript 1.2 и позднее)
  • taintEnabled специфицирует, включено ли разрушение данных/tainting (только JavaScript 1.1)

Некоторые объекты Navigator’а имеют свойства, значения которых являются массивами. Эти массивы используются для хранения информации, когда Вы заранее не знаете, сколько будет значений. В таблице показано, какие свойства каких объектов имеют массивы в качестве значений.

Таблица 11.2 Предопределённые массивы JavaScript

Объект Свойство Описание

Отражает тэги в порядке расположения в исходном коде.

Отражает тэги в порядке расположения в исходном коде.

Отражает тэги в порядке расположения в исходном коде (изображения, созданные конструктором Image() , не включаются в массив images ).

Отражает тэги и в порядке расположения в исходном коде.

Отражает элементы формы (такие как объекты Checkbox , Radio и Text ) в порядке расположения в исходном коде.

Отражает аргументы функции.

Отражает все MIME-типы, поддерживаемые клиентом (внутренне, через вспомогательные приложения или через plug-in’ы).

Отражает все plug-in’ы, установленные на клиенте, в порядке расположения в исходном коде.

Отражает опции объекта Select (тэги ) в порядке расположения в исходном коде.

Отражает все тэги в окне, содержащем тэг , в порядке расположения в исходном коде.

Отражает вхождения history окна.


Вы можете индексировать порядковыми числами или по именам (если определены). Например, если второй тэг имеет в атрибуте NAME значение «myForm», Вы можете обратиться к форме document.forms[1] , или document.forms[«myForm»] или document.myForm .

Например, определён следующий элемент:

Если Вы хотите обратиться к этому элементу формы по имени, можно специфицировать document.forms[«Comments»] .

Все предопределённые массивы JavaScript имеют свойство length, которое указывает количество элементов массива. Например, чтобы получить количество форм в документе, используйте свойство length : document.forms.length .

JavaScript 1.0. Вы обязаны индексировать массивы порядковыми числами, например document.forms[0] .

Метод write объекта document отображает вывод в Navigator’е. «Зачем?», спросите Вы, «ведь это уже делает HTML». Но в скрипте можно сделать то, чего не может обычный HTML. Например, Вы можете вывести текст на основе выполнения условия или аргументов переменной. Поэтому write это один из наиболее часто используемых методов JavaScript.

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

Вот скрипт, генерирующий динамический HTML с помощью JavaScript:

В HEAD этого документа определены две функции:

  • bar , которая отображает горизонтальную линию HTML, имеющую ширину, специфицированную аргументом функции.
  • output , которая отображает заголовок HTML того уровня, который специфицирован первым аргументом, и текст параграфа, специфицированный третьим аргументом.

Затем в тэге BODY документа эти две функции вызываются и дают на выходе:

Рисунок 11.2 Вывод, созданный с использованием функций JavaScript

Следующая строка создаёт вывод функции bar :

Заметьте, что в определении bar использованы знаки одинарных кавычек вместо двойных. Вы обязаны делать так при обозначении закавыченной строки внутри строкового литерала. Затем вызов bar с аргументом 25 производит вывод, эквивалентный следующему HTML:

write сопутствующий метод writeln , который добавляет последовательность символов «новая строка» (возврат каретки или возврат каретки + прогон строки, в зависимости от платформы) в конец своего вывода. Поскольку HTML обычно игнорирует символы новой строки, разницы между write и writeln нет, за исключением положения внутри таких тэгов, как PRE .

Печать вывода

Navigator версии 3.0 печатает вывод, созданный в JavaScript. Для распечатки вывода, пользователь выбирает Print из меню File Navigator’а. Navigator 2.0 не распечатывает вывод, создаваемый JavaScript.

Если Вы распечатываете страницу, содержащую слои/layers (Navigator 4.0 и позднее), каждый слой печатается отдельно на той же странице. Например, если три слоя перекрывают друг друга в браузере, распечатанная страница показывает каждый слой отдельно.

Если Вы выбрали Page Source из меню View Navigator’а или View Frame Source из контекстного меню (правой клавишей мыши), web-браузер отображает содержимое HTML-файла со сгенерированным HTML. Если Вы хотите просмотреть исходный HTML со скриптами генерирующими HTML (с методами document.write и document.writeln ), не используйте меню Page Source и View Frame Source. Тогда используйте протокол view-source: . Например, предположим, файл file://c|/test.html содержит такой текст:

При загрузке этого URL браузер выведет:

Если выбрать Page Source из меню View, браузер выведет:

Если загрузить view-source:file://c|/test.html , браузер выведет:

Отображение вывода

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

Оглавление | Назад | Вперёд | Индекс

Дата последнего обновления: 25 мая 1999 года.
Copyright (c) 1999 Netscape Communications Corporation

Javascript BOM : Navigator Object

Exploit the Navigator object to get details about browser and its extensions and plugins.

Javascript Browser Object Model : Navigator Object

The JavaScript window object property of navigator is used refer to the Navigator object, which contains all information related to browser, it vendor , version, plugins etc.

Earlier Navigator object was used only to determine whether clients systems were running, Internet Explorer or Netscape i.e browser-sniffing

Currently the navigator object can be used to check the Browser Version, whether Java is enabled, plugins attached etc.

Javascript Navigator Object: Properties

Property Description
appCodeName The Code name of the Browser.
appName The name of the Browser.
appVersion Specifies the Version of the Browser.
mimeTypes Array of MIME types registered with the browser.
platforms The operation system on which the browser runs.
userAgent The HTTP user-agent header sent from the browser to the server.

In the below demo, the special loop is used to assign each property of the navigator object to variable navigatorProperty.

Example: Javascript Navigator Object Properties

Give it a TRY! » Note: Each property and its value is displayed against each other.

Javascript Navigator Object : Plug-In Detection

The Navigator object is used mostly to detect the presence of plug-ins installed on the browser, it uses the plugins array for that purpose. The items in the array comprise of the following property.

name : The plug-in name.

description : The plug-in name.

filename : The filename of the plug-in.

length : The number of MIME types handled by the plugin.

Plug-Ins are programs which can be used by the browser to add abilities to play audio files, videos, animation, view PDF files etc. Eg: Adobe Acrobat Reader, Shockwave/Flash Player etc.

Example: Javascript Navigator Object Plug-In Detection

Give it a TRY! » Note: The plugins[] array contains all plugins installed on the browser.

Javascript Navigator Object : Get all Browser Information.

The JavaScript navigator object has a set of properties which can be used to get all browser Information, these properties can help you customise the Web Page.

Example : Javascript Navigator Object : Get Browser Information

Give it a TRY! » Note: The property platform specifies the operating system on which the browser is running.

Javascript Navigator Object : MIME Types

MIME(Multipurpose Internet Mail Extension) specifies the protocol standard used to exchange different types of data files over the Internet. Eg: Audio, video, text etc.

The mimeType object are predefined and are used to access the mimeTypes[] array which belongs to both the navigator object and plugin object.

Javascript Navigator Object: Properties

Property Description
description To provide description about the MIME Type.
enabledPlugin To point to the plugin object for the specified MIME type.
suffixes The extension of the file. Eg .png, .pdf
type To name the MIME type. eg: image/png

Example : Javascript Navigator Object : Get Browser Information

Give it a TRY! » Note: If the values are empty, it means that MIME type is null.

Выразительный JavaScript: Document Object Model (объектная модель документа)

Содержание

Когда вы открываете веб-страницу в браузере, он получает исходный текст HTML и разбирает (парсит) его примерно так, как наш парсер из главы 11 разбирал программу. Браузер строит модель структуры документа и использует её, чтобы нарисовать страницу на экране.

Это представление документа и есть одна из игрушек, доступных в песочнице JavaScript. Вы можете читать её и изменять. Она изменяется в реальном времени – как только вы её подправляете, страница на экране обновляется, отражая изменения.

Структура документа

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

У этой страницы следующая структура:

Структура данных, использующаяся браузером для представления документа, отражает его форму. Для каждой коробки есть объект, с которым мы можем взаимодействовать и узнавать про него разные данные – какой тег он представляет, какие коробки и текст содержит. Это представление называется Document Object Model (объектная модель документа), или сокращённо DOM.

Мы можем получить доступ к этим объектам через глобальную переменную document. Её свойство documentElement ссылается на объект, представляющий тег . Он также предоставляет свойства head и body, в которых содержатся объекты для соответствующих элементов.

Деревья

Вспомните синтаксические деревья из главы 11. Их структура удивительно похожа на структуру документа браузера. Каждый узел может ссылаться на другие узлы, у каждого из ответвлений может быть своё ответвление. Эта структура – типичный пример вложенных структур, где элементы содержат подэлементы, похожие на них самих.

Мы зовём структуру данных деревом, когда она разветвляется, не имеет циклов (узел не может содержать сам себя), и имеет единственный ярко выраженный «корень». В случае DOM в качестве корня выступает document.documentElement.

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

У типичного дерева есть разные узлы. У синтаксического дерева языка Egg были переменные, значения и приложения. У приложений всегда были дочерние ветви, а переменные и значения были «листьями», то есть узлами без дочерних ответвлений.

То же и у DOM. Узлы для обычных элементов, представляющих теги HTML, определяют структуру документа. У них могут быть дочерние узлы. Пример такого узла — document.body. Некоторые из этих дочерних узлов могут оказаться листьями – например, текст или комментарии (в HTML комментарии записываются между символами ).

У каждого узлового объекта DOM есть свойство nodeType, содержащее цифровой код, определяющий тип узла. У обычных элементов он равен 1, что также определено в виде свойства-константы document.ELEMENT_NODE. У текстовых узлов, представляющих отрывки текста, он равен 3 (document.TEXT_NODE). У комментариев — 8 (document.COMMENT_NODE).

То есть, вот ещё один способ графически представить дерево документа:

Листья – текстовые узлы, а стрелки показывают взаимоотношения отец-ребёнок между узлами.

Стандарт

Использовать загадочные цифры для представления типа узла – это подход не в стиле JavaScript. Позже мы встретимся с другими частями интерфейса DOM, которые тоже кажутся чуждыми и нескладными. Причина в том, что DOM разрабатывался не только для JavaScript. Он пытается определить интерфейс, не зависящий от языка, который можно использовать и в других системах – не только в HTML, но и в XML, который представляет из себя формат данных общего назначения с синтаксисом, напоминающим HTML.

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

Чтобы показать неудобную интеграцию с языком, рассмотрим свойство childNodes, которое есть у узлов DOM. В нём содержится объект, похожий на массив, со свойством length, и пронумерованные свойства для доступа к дочерним узлам. Но это – экземпляр типа NodeList, не настоящий массив, поэтому у него нет методов вроде forEach.

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

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

Обход дерева

Узлы DOM содержат много ссылок на соседние. Это показано на диаграмме:

Хотя тут показано только по одной ссылке каждого типа, у каждого узла есть свойство parentNode, указывающего на его родительский узел. Также у каждого узла-элемента (тип 1) есть свойство childNodes, указывающее на массивоподобный объект, содержащий его дочерние узлы.

В теории можно пройти в любую часть дерева, используя только эти ссылки. Но JavaScript предоставляет нам много дополнительных вспомогательных ссылок. Свойства firstChild и lastChild показывают на первый и последний дочерний элементы, или содержат null у тех узлов, у которых нет дочерних. previousSibling и nextSibling указывают на соседние узлы – узлы того же родителя, что и текущего узла, но находящиеся в списке сразу до или после текущей. У первого узла свойство previousSibling будет null, а у последнего nextSibling будет null.

При работе с такими вложенными структурами пригождаются рекурсивные функции. Следующая ищет в документе текстовые узлы, содержащие заданную строку, и возвращает true, когда находит:

Свойства текстового узла nodeValue содержит строчку текста.

Поиск элементов

Часто бывает полезным ориентироваться по этим ссылкам между родителями, детьми и родственными узлами и проходить по всему документу. Однако если нам нужен конкретный узел в документе, очень неудобно идти по нему, начиная с document.body и тупо перебирая жёстко заданный в коде путь. Поступая так, мы вносим в программу допущения о точной структуре документа – а её мы позже можем захотеть поменять. Другой усложняющий фактор – текстовые узлы создаются даже для пробелов между узлами. В документе из примера у тега body не три дочерних (h1 и два p), а целых семь: эти три плюс пробелы до, после и между ними.

Так что если нам нужен атрибут href из ссылки, мы не должны писать в программе что-то вроде: «второй ребёнок шестого ребёнка document.body». Лучше бы, если б мы могли сказать: «первая ссылка в документе». И так можно сделать:

У всех узлов-элементов есть метод getElementsByTagName, собирающий все элементы с данным тэгом, которые происходят (прямые или не прямые потомки) от этого узла, и возвращает его в виде массивоподобного объекта.

Чтобы найти конкретный узел, можно задать ему атрибут id и использовать метод document.getElementById.

Третий метод – getElementsByClassName, который, как и getElementsByTagName, ищет в содержимом узла-элемента и возвращает все элементы, содержащие в своём классе заданную строчку.

Меняем документ

Почти всё в структуре DOM можно менять. У узлов-элементов есть набор методов, которые используются для их изменения. Метод removeChild удаляет заданную дочерний узел. Для добавления узла можно использовать appendChild, который добавляет узел в конец списка, либо insertBefore, добавляющий узел, переданную первым аргументом, перед узлом, переданным вторым аргументом.

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

Метод replaceChild используется для замены одного дочернего узла другим. Он принимает два узла: новый, и тот, который надо заменить. Заменяемый узел должен быть дочерним узлом того элемента, чей метод мы вызываем. Как replaceChild, так и insertBefore в качестве первого аргумента ожидают получить новый узел.

Создание узлов

В следующем примере нам надо сделать скрипт, заменяющий все картинки (тег ) в документе текстом, содержащимся в их атрибуте “alt”, который задаёт альтернативное текстовое представление картинки.

Для этого надо не только удалить картинки, но и добавить новые текстовые узлы им на замену. Для этого мы используем метод document.createTextNode.

Получая строку, createTextNode даёт нам тип 3 узла DOM (текстовый), который мы можем вставить в документ, чтобы он был показан на экране.

Цикл по картинкам начинается в конце списка узлов. Это сделано потому, что список узлов, возвращаемый методом getElementsByTagName (или свойством childNodes) постоянно обновляется при изменениях документа. Если б мы начали с начала, удаление первой картинки привело бы к потере списком первого элемента, и во время второго прохода цикла, когда i равно 1, он бы остановился, потому что длина списка стала бы также равняться 1.

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

Для создания узлов-элементов (тип 1) можно использовать document.createElement. Метод принимает имя тега и возвращает новый пустой узел заданного типа. Следующий пример определяет инструмент elt, создающий узел-элемент и использующий остальные аргументы в качестве его детей. Эта функция потом используется для добавления дополнительной информации к цитате.

Атрибуты

К некоторым элементам атрибутов, типа href у ссылок, можно получить доступ через одноимённое свойство объекта. Это возможно для ограниченного числа часто используемых стандартных атрибутов.

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

Рекомендую перед именами придуманных атрибутов ставить “data-“, чтобы быть уверенным, что они не конфликтуют с любыми другими. В качестве простого примера мы напишем подсветку синтаксиса, который ищет теги

Функция highlightCode принимает узел

Есть один часто используемый атрибут, class, имя которого является ключевым словом в JavaScript. По историческим причинам, когда старые реализации JavaScript не умели обращаться с именами свойств, совпадавшими с ключевыми словами, этот атрибут доступен через свойство под названием className. Вы также можете получить к нему доступ по его настоящему имени “class” через методы getAttribute и setAttribute.

Расположение элементов (layout)

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

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

Размер и положение элемента можно узнать через JavaScript. Свойства offsetWidth и offsetHeight выдают размер в пикселях, занимаемый элементом. Пиксель – основная единица измерений в браузерах, и обычно соответствует размеру минимальной точки экрана. Сходным образом, clientWidth и clientHeight дают размер внутренней части элемента, не считая бордюра (или, как говорят некоторые, поребрика).

Самый эффективный способ узнать точное расположение элемента на экране – метод getBoundingClientRect. Он возвращает объект со свойствами top, bottom, left, и right (сверху, снизу, слева и справа), которые содержат положение элемента относительно левого верхнего угла экрана в пикселях. Если вам надо получить эти данные относительно всего документа, вам надо прибавить текущую позицию прокрутки, которая содержится в глобальных переменных pageXOffset и pageYOffset.

Разбор документа – задача сложная. В целях быстродействия браузерные движки не перестраивают документ каждый раз после его изменения, а ждут так долго. как это возможно. Когда программа JavaScript, изменившая документ, заканчивает работу, браузеру надо будет просчитать новую раскладку страницы, чтобы вывести изменённый документ на экран. Когда программа запрашивает позицию или размер чего-либо, читая свойства типа offsetHeight или вызывая getBoundingClientRect, для предоставления корректной информации тоже необходимо рассчитывать раскладку.

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

Стили

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

Атрибут style может содержать одно или несколько объявлений свойств (color), за которым следует двоеточие и значение. В случае нескольких объявлений они разделяются точкой с запятой: “color: red; border: none”.

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

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

Код JavaScript может напрямую действовать на стиль элемента через свойство узла style. В нём содержится объект, имеющий свойства для всех свойств стилей. Их значения – строки, в которые мы можем писать для смены какого-то аспекта стиля элемента.

Некоторые имена свойств стилей содержат дефисы, например font-family. Так как с ними неудобно было бы работать в JavaScript (пришлось бы писать style[«font-family»]), названия свойств в объекте стилей пишутся без дефиса, а вместо этого в них появляются прописные буквы: style.fontFamily

Каскадные стили

Система стилей в HTML называется CSS (Cascading Style Sheets, каскадные таблицы стилей). Таблица стилей – набор стилей в документе. Его можно писать внутри тега

«Каскадные» означает, что несколько правил комбинируются для получения окончательного стиля документа. В примере на стиль по умолчанию для

Приоритет самых поздних правил работает, когда у правил одинаковая детализация. Это мера того, насколько точно оно описывает подходящие элементы, определяемая числом и видом необходимых аспектов элементов. К примеру, правило для p.a более детально, чем правила для p или просто .a, и будет иметь приоритет.

Запись p > a <…>применима ко всем тегам , находящимся внутри тега и являющимся его прямыми потомками.
p a <…>применимо также ко всем тегам

В отличие от методов вроде getElementsByTagName, возвращаемый querySelectorAll объект не интерактивный. Он не изменится, если вы измените документ.

Метод querySelector (без All) работает сходным образом. Он нужен, если вам необходим один конкретный элемент. Он вернёт только первое совпадение, или null, если совпадений нет.

Расположение и анимация

Свойство стилей position сильно влияет на расположение элементов. По умолчанию оно равно static, что означает, что элемент находится на своём обычном месте в документе. Когда оно равно relative, элемент всё ещё занимает место, но теперь свойства top и left можно использовать для сдвига относительно его обычного расположения. Когда оно равно absolute, элемент удаляется из нормального «потока» документа – то есть, он не занимает место и может накладываться на другие. Кроме того, его свойства left и top можно использовать для абсолютного позиционирования относительно левого верхнего угла ближайшего включающего его элемента, у которого position не равно static. А если такого элемента нет, тогда он позиционируется относительно документа.

Мы можем использовать это для создания анимации. Следующий документ показывает картинку с котом, которая двигается по эллипсу.

Картинка отцентрирована на странице и ей задана position: relative. Мы постоянно обновляем свойства top и left картинки, чтобы она двигалась.

Скрипт использует requestAnimationFrame для вызова функции animate каждый раз, когда браузер готов перерисовывать экран. Функция animate сама опять вызывает requestAnimationFrame, чтобы запланировать следующее обновление. Когда окно браузера (или закладка) активна, это приведёт к обновлениям со скорость примерно 60 раз в секунду, что позволяет добиться хорошо выглядящей анимации.

Если бы мы просто обновляли DOM в цикле, страница бы зависла и ничего не было бы видно. Браузеры не обновляют страницу во время работы JavaScript, и не допускают в это время работы со страницей. Поэтому нам нужна requestAnimationFrame – она сообщает браузеру, что мы пока закончили, и он может заниматься своими браузерными вещами, например обновлять экран и отвечать на запросы пользователя.

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

Движение по кругу осуществляется с применением тригонометрических функций Math.cos и Math.sin. Я кратко опишу их для тех, кто с ними незнаком, так как они понадобятся нам в дальнейшем.

Math.cos и Math.sin полезны тогда, когда надо найти точки на круге с центром в точке (0, 0) и радиусом в единицу. Обе функции интерпретируют свой аргумент как позицию на круге, где 0 обозначает точку с правого края круга, затем нужно против часовой стрелки, пока путь диной в 2π (около 6.28) не проведёт нас по кругу. Math.cos считает координату по оси x той точки, которая является нашей текущей позицией на круге, а Math.sin выдаёт координату y. Позиции (или углы) больше, чем 2π или меньше чем 0, тоже допустимы – повороты повторяются так, что a+2π означает тот же самый угол, что и a.

Использование синуса и косинуса для вычисления координат

Анимация кота хранит счётчик angle для текущего угла поворота анимации, и увеличивает его пропорционально прошедшему времени каждый раз при вызове функции animation. Этот угол используется для подсчёта текущей позиции элемента image. Стиль top подсчитывается через Math.sin и умножается на 20 – это вертикальный радиус нашего эллипса. Стиль left считается через Math.cos и умножается на 200, так что ширина эллипса сильно больше высоты.

Стилям обычно требуются единицы измерения. В нашем случае приходится добавлять px к числу, чтобы объяснить браузеру, что мы считаем в пикселях (а не в сантиметрах, ems или других единицах). Это легко забыть. Использование чисел без единиц измерения приведёт к игнорированию стиля – если только число не равно 0, что не зависит от единиц измерения.

Программы JavaScript могут изучать и изменять текущий отображаемый браузером документ через структуру под названием DOM. Эта структура данных представляет модель документа браузера, а программа JavaScript может изменять её для изменения видимого документа. DOM организован в виде дерева, в котором элементы расположены иерархически в соответствии со структурой документа. У объектов элементов есть свойства типа parentNode и childNodes, которы используются для ориентирования на дереве.

Внешний вид документа можно изменять через стили, либо добавляя стили к узлам напрямую, либо определяя правила для каких-либо узлов. У стилей есть очень много свойств, таких, как color или display. JavaScript может влиять на стиль элемента напрямую через его свойство style.

Упражнения

Строим таблицу

Мы строили таблицы из простого текста в главе 6. HTML упрощает построение таблиц. Таблица в HTML строится при помощи следующих тегов:

Для каждой строки в теге

Элементы по имени тегов

Метод getElementsByTagName возвращает все дочерние элементы с заданным именем тега. Сделайте свою версию этого метода в виде обычной функции, которая принимает узел и строчку (имя тега) и возвращает массив, содержащий все нисходящие узлы с заданным именем тега.

Чтобы выяснить имя тега элемента, используйте свойство tagName. Заметьте, что оно возвратит имя тега в верхнем регистре. Используйте методы строк toLowerCase или toUpperCase.

Шляпа кота

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

Или пусть шляпа летает вокруг кота. Или ещё что-нибудь интересное придумайте.

Чтобы упростить расположение множества объектов, неплохо будет переключиться на абсолютное позиционирование. Тогда top и left будут считаться относительно левого верхнего угла документа. Чтобы не использовать отрицательные координаты, вы можете добавить заданное число пикселей к значениям position.

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

Первую группу свойств составляют свойства шрифтов:

font-size, font-family, font-weight, font-style.

Вторую группу свойств составляют свойства текста:

line-height, text-decoration, text-transform, text-align, text-indent.

Третью группу свойств составляют свойства блоков текста:

margin-left, margin-right, margin-top, margin-bottom, margin, padding-top, padding-right, padding-bottom, padding-left, paddings, border-top-width, border-bottom-width, border-left-width, border-right-width, border-width, border-style, border-color

Четвертую группу составляют описатели цвета фона и цвета текста:

color, background-image, background-color.

Кроме того, существуют свойства определяющие тип пульки у элементов списка и ряд других свойств элементов HTML-разметки.

Управление просмотром страниц Web-узла. JavaScript

Современные гипертекстовые информационные системы условно можно представить в виде совокупности нескольких компонентов: системы хранения гипертекстовых объектов, системы отображения гипертекстовых объектов, системы подготовки гипертекстовых объектов и системы программирования просмотра совокупности гипертекстовых объектов. С этой точки зрения технология World Wide Web только к 1996 году получила законченный, функционально полный вид. Первыми были разработаны системы хранения и просмотра (1989-1991 г.г.), которые продолжают развиваться и в настоящее время. После 1990 года стали появляться первые системы подготовки документов. Наконец, в 1995 году были предложены первые языки управления сценариями просмотра.

Программирование процедуры просмотра гипертекстовой базы данных не является изобретением Netscape, Microsoft или Sun. Практически все локальные гипертекстовые системы в той или иной степени имеют программные средства манипулирования гипертекстовыми объектами. В ряде случаев вся гипертекстовая база данных может быть представлена как одна большая программа, в которой гипертекстовые узлы — это программные модули, а связи между ними — это передача управления от одного модуля другому.

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

Программы просмотра гипертекстовых страниц традиционно называют скриптами (scripts) по аналогии с исполняемыми файлами, написанными для командных интерпретаторов типа sh. Собственно как это было и раньше в локальных системах, в программировании просмотра гипертекстовых документов World Wide Web существуют два подхода: создание интерпретируемых программой просмотра скриптов или компиляция байт-кода. Первый подход следует традиции World Wide Web, согласно которой для разработки гипертекстовой страницы нужен только обычный текстовый редактор и сам гипертекстовый документ должен легко читаться человеком-оператором. Второй подход позволяет повысить эффективность исполнения программы и защищенность кода от несанкционированных модификаций. Как первый, так и второй способ опираются на объектно-ориентированный подход к программированию. По поводу байт-кодов или мобильных кодов, как их еще называют, написано в контексте технологии программирования Java достаточно много, поэтому сосредоточим свое внимание на скриптах, а точнее на скриптах, написанных на языке JavaScript.

Модель объектов JavaScript — объекты Navigator’а

Идея JavaScript очень проста. Все операции, которые можно исполнять в программе на JavaScript, описывают действия над хорошо известными и понятными объектами, которыми являются элементы рабочей области программы Netscape Navigator и контейнеры языка HTML. Собственно объектная ориентированность JavaScript на этом и кончается. Есть только объекты с набором свойств и набор функций над объектами. Последние называются методами. Кроме методов существуют и другие функции, которые больше похожи на функции из традиционных языков программирования и позволяют работать со стандартными математическими типами или управлять процессом выполнения программы. Еще в JavaScript есть события — аналог программных прерываний. Эти события также ориентированы на работу в World Wide Web, например, загрузка страницы в рабочую область Navigator’a или выбор гипертекстовой ссылки. Используя события, автор гипертекстовой страницы и программы ее отображающей может организовать просмотр динамических объектов, например, бегущая строка, или управление многооконным интерфейсом.

Описание иерархии классов

Все встроенные объекты JavaScript берут свое начало от рабочей области Netscape, и их можно представить в виде следующей иерархии:

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

Методы объектов и свойства объектов. Управление потоком вычислений

Каждый из этих классов имеет функции управления объектами класса — методы. Самыми главными их этих методов являются те, которые позволяют переназначать значения объектов. Делается это обычно по операции присваивания. Вообще, все типы операторов, которые поддерживаются обычными языками программирования, реализованы JavaScript (+,-,*, /, %, >>, 0) < . >else

Тип переменной определяется по присвоенному ей значению.

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

События

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

Не будем перечислять все события, но упомянем о наиболее часто используемых:

    • onLoad — выполнение скрипта или функции при загрузке;
    • onChange — порождается при изменении значения элемента формы;
    • onClick — порождается при выборе объекта (button, checkbox и т.п.);
    • onSelect— порождается при выборе текстового объекта (text, textarea);
    • onSubmit — при нажатии на кнопку Submit;
    • onUnload — при переходе к другой странице.

Появление Netscape Navigator 3.0 и новой версии JavaScript 1.1 заставляет продолжить обзор возможностей управления сценариями просмотра Website, который был опубликован в предыдущем выпуске «Открытых Систем Сегодня» (CW N 46, 1996). В новой версии языка были введены: возможность взаимодействия JavaScript и Java, определение установленных plug-ins, определены новые типы объектов (Area, Function, Image) и ряд других особенностей, которые по мнению разработчиков должны повысить мощь программирования на JavaScript.

Массивы

Первый тип новых объектов, которые мы рассмотрим, являются массивы. Тип «Array» введен в JavaScript 1.1 для возможности манипулирования самыми разными объектами, которые отображаются Navigator’ом. Это — список всех гипертекстовых ссылок данной страницы Website, список всех картинок на данной странице, список всех applet’ов данной страницы, список всех элементов формы и т.п. Пользователь может создать и свой собственный массив, используя конструктор Array(). Делается это следующим образом:

new_array = new Array()
new_array5 = new Array(5)
colors = new Array («red»,»white»,»blue»)

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

colors = new Array()
colors[5] = «red»

В данном случае массив будет состоять из 6 элементов, т.к. первым элементом массива считается элемент с индексом 0. Для массивов определены три метода: join, reverse, sort. Join объединяет элементы массива в строку символов, в качестве аргумента в этом методе задается разделитель:

colors = new Array(«red»,»white»,»blue»)
string = acolors.join(«+»)

В результате выполнения присваивания значения строке символов string мы получим следующую строку:

string = «red + white + blue»

Другой метод, reverse, изменяет порядок элементов массива на обратный, а метод sort отсортировывает их в порядке возрастания. У массивов есть два свойства: length и prototype. Length определяет число элементов массива. Если нужно выполнить некоторую рутинную операцию над всеми элементами массива, то можно воспользоваться циклом типа:

color = new Array(«red»,»white»,»blue»)
n = 0 while(n != colors.length)

Свойство prototype позволяет добавить свойства к объектам массива. Однако наиболее часто, в программе на JavaScript используются встроенные массивы, главным образом графические образы (Images) и гипертекстовые ссылки (Links).

Графика

До Navigator 3.0 в JavaScript использовались только встроенные объекты типа Image. В новой версии языка появился конструктор для этого типа объектов:

new_image = new Image()
new_image = new Image (width,height)

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

img_array = new Array()
img_array[0] = new Image(50,100)
img_array[1] = new Image(50,100)
. img_array[99] = new Image(50,100)

У объекта Image существует 10 свойств, из которых, пожалуй, самым важным является src. Так, для присваивания конкретных картинок элементам массива img_array следует воспользоваться следующей последовательностью команд:

img_array[0].src = «IMAGE1.GIF»
img_array[1].src = «IMAGE2.GIF»
. img_array[99].src = «IMAGE100.GIF»

В данном случае можно было воспользоваться и циклом для присвоения имен, так как они могут быть составлены из констант и значения индексной переменной. В новой версии языка объект типа Image можно поименовать в HTML-теге IMG. После этого можно обращаться к нему по имени. При этом следует учитывать, что если Image используется внутри формы, то он является свойством этой формы. Это значит, что для следующего графического объекта должны быть использованы разные составные имена:

Илон Маск рекомендует:  Что такое код getpsp
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL