function f() { var i=5; k=7; } f(); alert(k); В примере выдается результат k=7, однако, хоть переменная и не объявлена, она внутри функции, т.е. локальная и не должна быть видима, или вторая и последующие все-таки становятся глобальными? |
Функции и объекты
Коллекции
Коллекция - это структура данных JavaScript, похожая на массив. Отличие коллекции от массивов заключается в том, что массивы программист создает сам в коде программы и заполняет их данными; коллекции же создаются браузером и "населяются" объектами, связанными с элементами Web-страницы. Коллекцию можно рассматривать как другой, зачастую более удобный способ доступа к объектам Web-страницы.
Например, если на странице имеются формы с именами f, g5 и h32, то у объекта document есть соответствующие свойства-объекты document.f, document.g5 и т.д. Но кроме того, у объекта document есть свойство forms, являющееся коллекцией (массивом) всех форм, и значит, к тем же самым объектам форм можно обратиться как document.forms[0], document.forms[1] и т.д. Это бывает удобным, когда необходимо выполнить какие-то действия со всеми объектами форм на данной странице. Указывая свойства того или иного объекта, мы обычно пишем коллекции со скобками: forms[], images[], frames[], чтобы подчеркнуть, что это не обычные свойства, а коллекции.
Нумеруются элементы коллекции, начиная с нуля, в порядке их появления в исходном HTML-файле. Доступ к элементам коллекций осуществляется либо по индексу (в круглых или квадратных скобках), либо по имени (тоже в круглых или квадратных скобках, либо через точку), например:
window.document.forms[4] // 5-я форма на странице window.document.forms(4) // равносильно предыдущему window.document.forms['mf'] // форма с именем 'mf' window.document.forms('mf') // равносильно предыдущему window.document.forms.mf // равносильно предыдущему window.document.mf // равносильно предыдущему
Способы в 3-4 строчках удобны, когда имя элемента коллекции хранится в качестве значения переменной. Например, если мы задали var w="mf", то мы можем обратиться к форме с именем " mf " как window.document.forms[w]. Именно так мы поступили выше в разделе про оператор for...in, когда выписывали список всех свойств объекта document.
Как и у обычных массивов, у коллекций есть свойство length, которое позволяет узнать количество элементов в коллекции. Например, document.images.length.
Перечислим основные коллекции в объектной модели документа.
Коллекция | Описание |
---|---|
window.frames[] | Все фреймы - т.е. объекты, отвечающие контейнерам <FRAME> |
document.all[] | Все объекты, отвечающие контейнерам внутри контейнера <BODY> |
document.anchors[] | Все якоря - т.е. объекты, отвечающие контейнерам <A> |
document.applets[] | Все апплеты - т.е. объекты, отвечающие контейнерам <APPLET> |
document.embeds[] | Все вложения - т.е. объекты, отвечающие контейнерам <EMBED> |
document.forms[] | Все формы - т.е. объекты, отвечающие контейнерам <FORM> |
document.images[] | Все картинки - т.е. объекты, отвечающие контейнерам <IMG> |
document.links[] | Все ссылки - т.е. объекты, отвечающие контейнерам <A HREF="..."> и <AREA HREF="..."> |
document.f.elements[] | Все элементы формы с именем f - т.е. объекты, отвечающие контейнерам <INPUT> и <SELECT> |
document.f.s.options[] | Все опции (контейнеры <OPTION> ) в контейнере <SELECT NAME=s> в форме <FORM NAME=f> |
navigator.mimeTypes[] | Все типы MIME, поддерживаемые браузером (список см. на сайте IANA) |
function_name.arguments[] | Все аргументы, переданные функции function_name() при вызове |
Cвойства
Многие HTML-контейнеры имеют атрибуты. Как мы уже знаем, каждому контейнеру соответствует объект. При этом соответствии атрибутам отвечают свойства объекта. Соответствие между атрибутами HTML-контейнеров и свойствами DOM-объектов не всегда прямое. Обычно каждому атрибуту отвечает некоторое свойство объекта. Но, во-первых, название этого свойства не всегда легко угадать по названию атрибута, а во-вторых, у объекта могут быть свойства, не имеющие аналогов среди атрибутов. Кроме того, как мы знаем, атрибуты являются регистро-независимыми, как и весь язык HTML, тогда как свойства объектов нужно писать в точно определенном регистре символов.
Например, контейнер якоря <A ...>...</A> имеет атрибут HREF, который превращает его в гипертекстовую ссылку:
<A HREF="http://intuit.ru/">intuit</A>
Данной гиперссылке соответствует объект (класса URL ) - document.links[0], если предполагать, что это первая ссылка в нашем документе. Тогда атрибуту HREF будет соответствовать свойство href этого объекта. К свойству объекта можно обращаться с помощью точечной нотации: объект.свойство . Например, чтобы изменить адрес, на который указывает эта ссылка, мы можем написать:
document.links[0].href='http://ya.ru/';
К свойствам можно также обращаться с помощью скобочной нотации: объект['свойство'] . В нашем примере:
document.links[0]['href']='http://ya.ru/';
У объектов, отвечающих гиперссылкам, есть также свойства, не имеющие аналогов среди атрибутов. Например, свойство document.links[0].protocol в нашем примере будет равно "http:" и т.д. Полный перечень свойств объектов класса URL Вы найдете в "Программируем гипертекстовые переходы" .
Методы
В терминологии JavaScript методы объекта определяют функции, с помощью которых выполняются действия с этим объектом, например, изменение его свойств , отображения их на web-странице, отправка данных на сервер, перезагрузка страницы и т.п.
Например, если у нас есть ссылка <A HREF="http://intuit.ru/">intuit</A> (будем считать, она первая в нашем документе), то у соответствующего ей объекта document.links[0] есть метод click(). Его вызов в любом месте JavaScript-программы равносилен тому, как если бы пользователь кликнул по ссылке, что демонстрирует пример:
<A HREF="http://intuit.ru/">intuit</A> <SCRIPT> document.links[0].click(); </SCRIPT>
При открытии такой страницы пользователь сразу будет перенаправлен на сайт ИНТУИТ. Обратите внимание, что скрипт написан после ссылки. Если бы мы написали его до ссылки, то поскольку в этот момент ссылки (а значит и объекта) еще не существует, браузер выдал бы сообщение об ошибке.
Некоторые методы могут применяться неявно. Для всех объектов определен метод преобразования в строку символов: toString(). Например, при сложении числа и строки число будет преобразовано в строку:
"25"+5 = "25"+(5).toString() = "25"+"5" = "255"
Аналогично, если обратиться к объекту window.location (рассматриваемом в следующей лекции) в строковом контексте, скажем, внутри вызова document.write(), то неявно будет выполнено это преобразование, и программист этого не заметит, как если бы он распечатывал не объект, а строку:
<SCRIPT> document.write('Неявное преобразование: '); document.write(window.location); document.write('<BR>Явное преобразование: '); document.write(window.location.toString()); </SCRIPT>
Тот же эффект можно наблюдать для встроенных объектов типа Date:
<SCRIPT> var d = new Date(); document.write('Неявное преобразование: '); document.write(d); document.write('<BR>Явное преобразование: '); document.write(d.toString()); </SCRIPT>
Результат исполнения получите сами.
События
Кроме методов и свойств, объекты характеризуются событиями. Собственно, суть программирования на JavaScript заключается в написании обработчиков этих событий. Например, с объектом типа button (контейнер INPUT типа button - "кнопка") может происходить событие Click, т.е. пользователь может нажать на кнопку. Для этого атрибуты контейнера INPUT расширены атрибутом обработки этого события - onClick. В качестве значения этого атрибута указывается программа обработки события, которую должен написать на JavaScript автор HTML-документа:
<INPUT TYPE=button VALUE="Нажать" onClick="alert('Пожалуйста, нажмите еще раз')">
Обработчики событий указываются в специально созданных для этого атрибутах у тех контейнеров, с которыми эти события связаны. Например, контейнер BODY определяет свойства всего документа, поэтому обработчик события "завершена загрузка всего документа" указывается в этом контейнере как значение атрибута onLoad.
Примеры событий: нажатие пользователем кнопки в форме, установка фокуса в поле формы или увод фокуса из нее, изменение введенного в поле значения, нажатие кнопки мыши, отпускание кнопки мыши, щелчок кнопкой мыши на объекте (ссылке, поле, кнопке, изображении и т.п.), двойной щелчок кнопкой мыши на объекте, перемещение указателя мыши, выделение текста в поле ввода или на странице и другие. Однако, некоторые изменения, происходящие на странице, не генерируют никаких событий; например: изменение значения в поле ввода не пользователем, а скриптом, изменение фона документа, изменение (скриптом) значения атрибута HREF ссылки, а также изменение большинства других атрибутов HTML-контейнеров. Обо всех важных событиях и об их "перехвате" будет рассказываться далее в соответствующих лекциях.
Разные браузеры могут вести себя по-разному при возникновении событий. Рассмотрим следующий пример, позволяющий определить, в каком порядке вызываются обработчики событий при клике либо двойном клике мыши на ссылке или кнопке:
<SCRIPT> function show_MouseDown() { rrr.innerHTML+='мышь нажали (MouseDown)<br>'; } function show_Click() { rrr.innerHTML+='клик мыши (Click)<br>'; } function show_MouseUp() { rrr.innerHTML+='мышь отжали (MouseUp)<br>'; } function show_DblClick() { rrr.innerHTML+='двойной клик (DblClick)<br>'; } </SCRIPT> <A HREF="javascript:void(0);" onMouseDown="show_MouseDown();" onClick="show_Click();" onMouseUp="show_MouseUp();" onDblClick="show_DblClick();">Ссылка</A> <INPUT TYPE=button VALUE="Кнопка" onMouseDown="show_MouseDown();" onClick="show_Click();" onMouseUp="show_MouseUp();" onDblClick="show_DblClick();"> <BR><SPAN ID="rrr"></SPAN>3.2. Слежение за событиями Click и DblClick
Проверьте работу этой странички в Вашем браузере. При одиночном клике на ссылке или кнопке события возникают в порядке: MouseDown, MouseUp, Click, что логично. При двойном же клике последовательность происходящих событий в разных браузерах разная:
в браузере Mozilla Firefox 3.08: MouseDown, MouseUp, Click, MouseDown, MouseUp, Click, DblClick в браузере Internet Explorer 7.0: MouseDown, MouseUp, Click, MouseUp, DblClick
Как видим, в Mozilla Firefox последовательность событий более логична - она состоит из двух последовательностей событий, отвечающих одиночному клику, и далее событие двойного клика. Вы можете написать чуть более изощренный скрипт, показывающий, что в IE7 действительно не происходит второго события Click при двойном клике мышью.