создание и продвижение сайта (вбиваю в ТОП-10, как гвозди)Настройка и сопровождение платной рекламы яндекс.директ

6. Программируем гипертекстовые переходы. JavaScript (от intuit.ru)

Рассматриваются вопросы работы с коллекцией гипертекстовых ссылок и программирования гипертекстовых переходов в зависимости от условий просмотра HTML-страниц и действий пользователя.

Для начала нам нужно разделить несколько понятий: применимость URL в атрибутах HTML-контейнеров; коллекция гипертекстовых ссылок; объекты класса URL.

Адреса URL могут использоваться в атрибутах многих HTML-контейнеров, например:

  • ссылки (URL в атрибуте HREF контейнера A);
  • активные области (URL в атрибуте HREF контейнера AREA);
  • картинки (URL в атрибуте SRC контейнера IMG);
  • формы (URL в атрибуте ACTION контейнера FORM);
  • внешние скрипты (URL в атрибуте SRC контейнера SCRIPT);
  • связанные документы (URL в атрибуте HREF контейнера LINK).

    Гипертекстовая ссылка в HTML-документе - это область HTML-страницы, по которой можно "кликнуть" (или выбрать ее иным способом), чтобы перейти к просмотру другого HTML-документа. Из всех перечисленных выше вариантов применения URL гипертекстовыми ссылками являются лишь 1-е два. В объектной модели документа (DOM) они собраны в единую коллекцию гипертекстовых ссылок document.links[]. Нумерация в ней начинается с нуля (как обычно), в порядке появления ссылок в документе.

    Обратите внимание, что в принципе могут существовать ссылки, по которым невозможно "кликнуть", т.к. они занимают нулевую площадь web-страницы; например, контейнер <A> с пустым содержимым, т.е. <A HREF="//ya.ru/"></A>, или контейнер <AREA>, ограничивающий фигуру нулевой площади. Тем не менее все они считаются гипертекстовыми ссылками и содержатся в коллекции document.links[]. С другой стороны, в коллекцию document.links[] не попадают якоря, то есть контейнеры <A>, не имеющие атрибута HREF (якоря нужны, чтобы задать место, на которое можно сослаться из другой гиперссылки). Все контейнеры <A> (как якоря, так и гиперссылки) собраны в коллекции document.anchors[]; в этой лекции, однако, она нас не будет интересовать.

    В объектной модели документа DOM объекты класса URL имеют такие свойства, как href, protocol, hostname и т.д. (полный перечень см. ниже). В класс URL входят объекты коллекции document.links[], а также объект window.location, рассматривавшийся в лекции 4. Конечно, помимо общих свойств, перечисленных ниже, эти объекты могут иметь свои специфичные только для них свойства, методы и события. Например, у объекта window.location есть метод reload(), тогда как у ссылок его нет, но у них есть обработчик события onClick. Мы начнем с рассмотрения объектов класса URL.

    Объекты URL

    Объект класса URL обладает свойствами, которые определены схемой URL. В качестве примера рассмотрим ссылку:

    http://1.ru:80/dir/page.cgi?product=phone&id=3#mark

    Тогда ее свойства примут следующие значения (обратите внимание, что значение поля search начинается со знака "?", а значение hash - со знака "#")

    Свойства объекта URL
    СвойствоЗначение
    hrefhttp://1.ru:80/dir/page.cgi?product=phone&id=3#mark
    protocolhttp:
    hostname 1.ru
    port80
    host1.ru:80
    pathnamedir/page.cgi
    search?product=phone&id=3
    hash#mark

    Как Вы помните из прошлых лекций, к свойствам можно обращаться, используя точечную нотацию (document.links[0].host) или скобочную нотацию (document.links[0]["host"]). Свойства объекта класса URL дают программисту возможность менять только часть URL-адреса. Наиболее интересно это выглядит в объекте window.location, когда при изменении его свойства href происходит загрузка нового документа.

    Свойство href является свойством по умолчанию. Это значит, что вместо window.location.href="…" можно писать window.location="…", а опуская window (который является объектом по умолчанию), можно писать location.href="…" и даже location="…" - эффект будет тот же: загрузится страница с новым адресом. С этим, однако, стоит быть осторожнее, чтобы данный оператор присваивания не находился в контексте, где объектом по умолчанию может быть какой-либо другой объект, например, внутри оператора with.

    Обратите внимание, что свойства объекта URL взаимозависимы, точнее, свойство href зависит от остальных свойств, а остальные свойства зависят от href. Так, если присвоить новый URL свойству href объекта, то автоматически изменятся и все остальные свойства, разобрав данный URL на составные части. И наоборот, если, например, изменить значение свойства protocol с http: на ftp:, то изменится и значение свойства href.

    Коллекция ссылок links[]

    К встроенным гипертекстовым ссылкам относятся собственно ссылки (<A HREF=…>…</A>) и ссылки "чувствительных" графических картинок. Все вместе они составляют коллекцию (встроенный массив) гипертекстовых ссылок документа document.links[].

    К сожалению, обратиться по имени к гипертекстовой ссылке (т.е. как document.имя_ссылки) нельзя, даже несмотря на то, что у ссылки может быть задан атрибут NAME. Говоря точнее, такое обращение не рекомендуется в силу различий между браузерами. Поэтому обращаться к ним можно только через коллекцию ссылок по индексу: document.links[3] - это 4-я ссылка в документе. Стандарт также предусматривает обращение к ссылкам через коллекцию по имени: document.links["имя_ссылки"], однако это работает не во всех браузерах (в Mozilla Firefox работает, в IE7 нет). Поэтому в дальнейшем, в целях совместимости, мы будем обращаться к ссылкам через коллекцию по их индексу.

    В качестве примера распечатаем гипертекстовые ссылки некоторого документа:

    for(i=0;i<document.links.length;i++)
    document.write(document.links[i].href+"<p>");
    

    В результате можем получить список, например, такой:

    http://1.ru/help/index.html
    http://1.ru/help/terms.html
    http://1.ru/help/shop.html
    

    Вставим в документ контейнер MAP с 2 ссылками, привязанными к областям (даже) нулевого размера:

    <MAP NAME=test>
    <AREA SHAPE=rect COORDS="0,0,0,0" HREF="javascript:alert('Область 1')">
    <AREA SHAPE=rect COORDS="0,0,0,0" HREF="javascript:alert('Область 2')">
    </MAP>
    

    И снова распечатаем массив ссылок - получим уже:

    http://1.ru/help/index.html
    http://1.ru/help/terms.html
    http://1.ru/help/shop.html
    javascript:alert('Область 1');
    javascript:alert('Область 2');
    

    Две новые ссылки - это ссылки из контейнера MAP, который не отображается, но ссылки из него попадают в коллекцию ссылок links[]. При этом они могут попасть между обычными гипертекстовыми ссылками, если контейнер MAP расположить внутри текста документа. Итак, ссылки, создаваемые контейнерами <A HREF="…"> и <AREA HREF="…">, равноправно присутствуют в коллекции document.links[].

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

    Выше мы перечислили свойства объекта класса URL. Теперь покажем, как при помощи JavaScript-кода можно этими свойствами управлять.

    Пример 6.1 (кликните, чтобы открыть его в новом окне; посмотреть исходный HTML-код можно, нажав правой кнопкой мыши и выбрав соответствующий пункт).

    Рассмотрим меню типа "записная книжка". Конечно, это не настоящая записная книжка. Поле формы заполняется только при выборе гипертекстовой ссылки, расположенной над этим полем. Единственная цель данного примера - показать, как изменяется значение атрибута HREF (оно отображается в поле status окна браузера при наведении указателя мыши на ссылку). В этом примере изменение свойства href у ссылок производится точно так же, как изменение свойства src у картинок и свойства value у полей ввода в форме:

    document.links[i+3].href=…
    document.images[i+3].src=…
    document.f.elements[i].value=…
    

    На нашей странице имеется 6 ссылок, 6 картинок и 3 поля ввода. 1-е три ссылки и картинки (с номерами 0,1,2) всегда неизменны. Последние же три ссылки и картинки (т.е. с номерами 3,4,5) мы меняем вышеприведенными операторами (поэтому в них индекс i+3, где i=0,1,2). Как вы видите, мы меняем значение href целиком. Однако URL можно менять и частично.

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

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

    <A HREF="//1.ru/department/internet/js/">Курс по JavaScript</A>
    

    Проверьте, что значение свойства document.links[0].pathname сейчас равно "department/internet/js/". Применим оператор:

    document.links[0].pathname="news/"
    

    Теперь эта ссылка указывает на адрес http://1.ru/news/.

    События MouseOver и MouseOut

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

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

    <A HREF="javascript:ShowMenu(0);void(0);">…</A>
    

    открывавшие подменю, когда пользователь кликал по ссылке, на строчки вида:

    <td><a href="javascript:void(0);" onMouseOver="ShowMenu(0);">…</A>
    

    открывающие подменю при наведении указателя мыши на пункт меню верхнего уровня. Выражения "javascript:void(0);" мы оставили в атрибуте HREF, чтобы ничего не происходило, если пользователь случайно кликнет по пункту меню верхнего уровня.

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

    <A HREF="javascript:void(0);"
    onMouseOver="document.pic1.src='pic1.gif';"
    onMouseOut="document.pic1.src='pic1_.gif';">
    <IMG NAME=pic1 src=pic1_.gif></A>
    

    Как уже рассказывалось в лекции 4, при возникновении события MouseOver у гиперссылки браузер показывает URL этой ссылки в поле статуса, а при возникновении события MouseOut восстанавливает в поле статуса прежнюю надпись. Перехватить первое событие (например, отменить вывод URL в строке статуса) можно, указав в его обработчике return true. Перехватить второе событие невозможно.

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

    URL-схема "JavaScript:"

    Для программирования гипертекстовых переходов в спецификацию URL разработчики JavaScript ввели, по аналогии с URL-схемами http, ftp и т.п., отдельную URL-схему javascript. Она уже упоминалась во вводной лекции при обсуждении вопроса о том, куда можно поместить JavaScript-программу в HTML-документе. Здесь мы рассмотрим ее подробнее.

    Схема URL javascript: используется следующим образом:

    <A HREF="JavaScript:код_программы">…</A>
    <FORM ACTION="JavaScript:код_программы" …> … </FORM>
    

    Рассмотрим пример гипертекстовой ссылки, в URL которой использована схема javascript:

    <A HREF="javascript:alert('Спасибо!');">Кликните</A>
    

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

    В общем случае, после "javascript:" может стоять произвольная программа JavaScript. Что в этом случае будет происходить, если кликнуть такую ссылку? Ответ следующий: сначала JavaScript-программа будет исполнена, в результате чего будет вычислено ее значение (которым всегда считается значение последнего оператора в программе). Затем, если это значение неопределено (undefined), то далее ничего не произойдет; если же полученное значение определено, то на экран будет выведена HTML-страница с этим результатом (преобразованным в строку и воспринятым как HTML-документ, который в том числе может содержать и HTML-тэги).

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

    <A HREF="javascript: 2+8; 5+7;">ссылка</A>
    

    мы получим страницу, на которой написан результат последнего выражения 12 (первое выражение 2+8, конечно, тоже будет вычислено, но его результат никуда не пойдет). Если же кликнуть по такой ссылке:

    <A HREF="javascript: '<H1>Ready!<H1>';">Кликните</A>
    

    то в окне браузера откроется страница, исходный HTML-код которой есть <H1>Ready!<H1>. Если нужно, чтобы при клике по ссылке просто выполнились какие-то действия и более ничего не происходило (в частности, не происходил переход к какой-либо другой странице), то в конце программы можно поместить оператор void(0) либо void(выражение). Эта функция вычисляет переданное в нее выражение и не возвращает никакого значения. Пример:

    <A HREF="javascript: document.bgColor='green'; void(0);">Кликните</A>
    

    Если кликнуть по такой ссылке, то изменится цвет фона, и больше ничего не произойдет. Без void(0) нам бы открылась web-страница со словом green.

    Все сказанное справедливо и для использования URL-схемы "javascript:" в атрибуте ACTION контейнера <FORM>, за одним нюансом: в этом случае необходимо, чтобы в качестве метода доступа был указан MEthOD="POST". Дело в том, что при использовании метода GET при отправке данных формы (т.е. при возникновении события Submit) к адресу URL, указанному в атрибуте ACTION, добавляется строка "?имя=значение&имя=значение&…", составленная из имен и значений элементов формы. Конечно же, такое выражение не является корректной JavaScript-программой, и браузеры могут выдавать сообщения об ошибке (а могут и не выдавать, а просто не выполнять программу). Пример:

    <FORM NAME=f MEthOD=post
    ACTION="javascript:alert('Длина строки='+form.e.value.length);">
    <INPUT NAME=e>
    <INPUT TYPE=submit VALUE="Длина">
    </FORM>
    

    Если ввести любую строку в поле ввода и нажать кнопку, то будет выведена длина строки. Этот пример был создан лишь для демонстрации URL-схемы "javascript:"; он весьма искусственный, т.к. в данном случае более уместно было бы использовать обработчик события onClick или onSubmit. Об этом и других применениях JavaScript в обработке форм рассказывается в лекции, посвященной программированию форм.

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

    У гипертекстовой ссылки помимо URL, указанного в атрибуте HREF, можно указать действия, которые браузер должен выполнить, когда пользователь кликнет по данной ссылке, перед тем, как перейти по указанному URL. Соответствующая программа JavaScript называется обработчиком события Click и помещается в атрибут onClick контейнера <A>. Если обработчик события возвращает значение false (это можно реализовать путем помещения в конец обработчика команды return false), то переход по адресу URL, указанному в атрибуте HREF, не будет совершен. Если же обработчик возвращает true либо ничего не возвращает, то после выполнения обработчика события будет совершен переход по адресу URL. Например:

    <A onClick="return confirm('Хотите посетить сайт INTUIT?')"
    HREF="//1.ru/">Перейти на сайт INTUIT</A>
    

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

    Если в атрибуте ссылки (например, HREF, onClick и т.п.) пишется JavaScript-код, в котором надо сослаться на свойство или метод этой ссылки, то, как и в случае форм, можно пользоваться сокращенной записью - не указывать объект данной ссылки, либо (для большей ясности кода) вместо него писать this. Например, пусть у нас имеется 5-я ссылка в документе, и мы хотим в ее обработчике onMouseOver сослаться на свойство href данной ссылки, или вызвать метод click() данной ссылки. Тогда в этом контексте вместо document.links[5].href можно писать this.href или просто href, а вместо document.links[5].click() писать this.click() или просто click(). Это не только укорачивает код, но и избавляет нас от необходимости привязываться к конкретному номеру данной ссылки, который в любой момент может измениться.

    И последнее замечание. Часто для того, чтобы скрипт запускался, когда посетитель кликает ссылку, программисты пишут что-то такое:

    <A HREF="#" onClick="программа JavaScript">…</A>
    <A HREF="javascript:void(0)" onClick="программа JavaScript">…</A>
    <A HREF="javascript: программа JavaScript">…</A>
    

    При этом код выполняется и, на 1-й взгляд, все нормально. Но на 2-й взгляд становится видно, что после клика на ссылку могут прекратить грузиться недогруженные элементы страницы (большие картинки и т.п.), останавливаются анимированные GIF'ы и, быть может, происходит что-то еще из этой серии. Все дело тут в том, что браузер считает клик пользователя по ссылке переходом на другую страницу, поэтому полагает, что заботиться о текущей странице больше не надо, ведь она с секунды на секунду заменится новой. Решение здесь такое: если вы рассчитываете при клике пользователя по ссылке оставить его на текущей странице, то не забудьте прописать выход return false из обработчика события onClick, например:

    <a href="#" onClick="программа JavaScript;return false;">
    

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

  • Отвечу на любые вопросы. С уважением, Дмитрий Владимирович.

    Ваше письмо×
    Free Web Hosting