Опубликован: 01.09.2010 | Уровень: для всех | Доступ: платный | ВУЗ: Сибирский федеральный университет
Лекция 11:

События. Объект event

Пример: Фотогалерея

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Моя галерея</title>
</head>
<body>
  <div>
    <div id="gallery">
      <a href="images/big/Photo1.jpg">
        <img src="images/small/Photo1.jpg" alt="Photo 1" /></a>
      <a href="images/big/Photo2.jpg">
        <img src="images/small/Photo2.jpg" alt="Photo 2" /></a>
      <a href="images/big/Photo3.jpg">
        <img src="images/small/Photo3.jpg" alt="Photo 3" /></a>
    </div>
  </div>
</body>
</html>

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

<script type="text/javascript" src="Gallery.js"></script>

Каскадная таблица стилей BigImg.css описывает стили двух элементов, контейнера с абсолютным позиционированием на странице и вложенного в него элемента div.

#BigImgContainer
{
	border:solid 1px #ccc;
	background:#fff;
	width:150px;
	height:150px;
	position:absolute;
	top:100px;
	left:200px;
	padding:8px;
	display:none;
}
#BigImgContainer div
{
	color:Red;
}

Весь сценарий реализован в файле Gallery.js.

/*
Все свойства и методы объект document доступны только после загрузки страницы
поэтому помещаем код в обработчик window.onload
*/
window.onload = function() {
    // находим элемент, в котором должны располагаться 
    // гиперссылки на изображения
    var oGallery = document.getElementById('gallery');
    if (!oGallery) {
        // элемент не найден. сообщаем инструкции по использованию
        alert("Для правильной работы в документе должен быть элемент с id='gallery'\nПример:\n\
<div id='gallery'>\n\
        <a href='MyBigPicture.jpg'><img src='SmallPic.jpg'></a>\n</div>");
        return; //выход из функции. Дальнейшие инструкции не выполняются
    } // if

    //Галерея найдена. Можно продолжать.
    // загружаем таблицу стилей
    var oLink = document.createElement('link');
    oLink.rel = 'stylesheet';
    oLink.type = 'text/css';
    oLink.href = 'BigImg.css';
    //и добавляем ее в элемент head
    document.documentElement.firstChild.appendChild(oLink);

    // создаем рамку, в которую будет загружаться изображение
    var oDiv = document.createElement('div');
    oDiv.id = 'BigImgContainer';
    //создаем вспомогательный элемент, 
    //отображаемый во время загрузки изображения
    var oLoading = document.createElement('div');
    oLoading.innerHTML = 'Идет загрузка...';
    // создаем объект изображение
    var oBigImg = new Image();
    //добавляем созданные объекты в дерево документа
    oDiv.appendChild(oLoading);
    oDiv.appendChild(oBigImg);
    document.body.appendChild(oDiv);

    //находим все гиперссылки в блоке gallery
    var oAnchors = oGallery.getElementsByTagName('a');
    for (var i = 0, n = oAnchors.length; i < n; i++) {
        //каждый элемент связываем с функцией-обработчиком
        oAnchors[i].onclick = function() {
            oDiv.style.width = ''; // вернуть к заданному по умолчанию
            oDiv.style.height = '';
            oDiv.style.display = 'block';
            oBigImg.style.display = 'none';
            // Загрузка мжет занять время. Показываем сообщение
            oLoading.style.display = 'block';
            //запускаем загрузку изображения
            oBigImg.src = this.href; // this == oAnchors[i]
            // Функция должна возвращать false, 
            // чтобы предотвратить переход по ссылке
            return false;
        } //oAnchors[i].onclick
    } //for

    //функция будет выполняться каждый раз после загрузки нового изображения
    oBigImg.onload = function() {
        // мы не знаем размеров изображения, пока оно не загружено
        oDiv.style.width = this.width + 'px'; // this == oBigImg
        oDiv.style.height = this.height + 'px';
        oLoading.style.display = 'none';
        oBigImg.style.display = 'block';
    } //oBigImg.onload

    // скрываем рамку с изображением по щелчку мыши
    oDiv.onclick = function() {
        this.style.display = 'none'; // this == oDiv
    } //oDiv.onclick
}  //window.onload

Сценарий содержит единственную анонимную функцию, которая вызывается автоматически после окончания загрузки HTML-документа. Внутри функции производит проверка наличия элемента, в котором должны располагаться ссылки, после чего создается контейнер для большой фотографии и объект Image, изначально не связанный с файлом изображения. Далее сценарий находит все гиперссылки, расположенные в объекте oGallery ( <div id="gallery"> ), и создает для каждой из них собственный обработчик события onclick. Гиперссылка имеет встроенное действие по щелчку мыши, но событие onclick происходит раньше, что позволяет предотвратить встроенное действие. Внутри обработчика происходит визуализация контейнера oDiv и инициализация загрузки большого изображения. Загрузка всегда происходит асинхронно, и функция-обработчик не дожидается ее окончания и возвращает false, чтобы предотвратить переход по гиперссылке. По окончании загрузки изображения срабатывает обработчик события oBigImg.onload. Только в этот момент сценарий может определить размер полученного изображения и скорректировать под него размеры контейнера. Наконец, обработчик oDiv.onclick позволяет убрать контейнер с изображением с экрана. Сценарий работает в любом браузере, поддерживающем JavaScript.

Об использовании ключевого слова this

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

//Пример 1
  function MyFoo(x, y) {
    this.x = x;
    this.y = y;
  }

  //Корректный вызов.
  var obj1 = new MyFoo(1, 2);
  /*
  MyFoo является конструктором объекта obj1, this является ссылкой на этот объект,
   который получает свойства x и y со значениями 1 и 2.
  */

  // Некорректный вызов.
  var obj2 = MyFoo(1, 2);
  /*
  MyFoo вызвана как обычная функция. Такой вызов осуществляется 
   в контексте объекта window. Объект window приобретает свойства x и y 
   со значениями 1 и 2, переменная obj2 значение undefined 
   (поскольку MyFoo не возвращает значения).
  */
  //Пример 2
  function SumSquares() {
    return this.x * this.x + this.y * this.y;
  }
  // Добавляем функцию SumSquares к методам объектов MyFoo.
  MyFoo.prototype.SumSquares = SumSquares;
  // Обратите внимание на отсутствие круглых скобок.

  //Корректный вызов.
  var a = obj1.SumSquares();
  // Здесь круглые скобки обязательны

  //Некорректный вызов.
  var b = SumSquares();
  /*
  Функция вызвана в контексте объекта window, у которого нет (не предполагается) свойств x и y.
  */
  //Чтобы избежать ошибок как в примере 2, 
  //лучше задать метод SumSquares как анонимную функцию.
  MyFoo.prototype.SumSquares = function() {
    return this.x * this.x + this.y * this.y;
  }

Вопросы

  1. Что такое событие?
  2. Перечислите основные события.
  3. Перечислите свойства объекта event.
  4. Как получить доступ к объекту event в функции-обработчике события - в IE и других браузерах?
  5. Как получить доступ к элементу-источнику события, имея объект event?
  6. Как передать обработчику события ссылку на элемент-источник?
  7. Как происходит связывание элемента-источника и события с функцией-обработчиком?
  8. Какой смысл имеет ключевое слово this в функциях-обработчиках событий?
Юрий Шах
Юрий Шах

Профессиональный веб-дизайн: Введение в современные веб-технологии
Самостоятельная работа 4

"3. Создание внешней таблицы.

Теперь создайте таблицу с двумя строками. Во второй строке создайте две ячейки - в первую переместите таблицу цифр, а во вторую - таблицу знаков."

Как в ячейку <td> поместить таблицу? Таблица же сама состоит из ячеек. Исходя из задания следует, что <td> может быть родителем для <td>, но это противоречит правилам HTML?
Если не прав - поправьте.
Также прошу разъяснить, как именно выполнить занное условие - поместить в табличную ячейку таблицу цифр, а в другую ячейку - таблицу знаков? 

Елена Сапегова
Елена Сапегова

После прохождения теоретической части пришло письмо об окончании теоретической части курса, будет ли практическая часть?

Анатолий Федоров
Анатолий Федоров
Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989