Рубрика «JavaScript»

Реагирование на события в JavaScript

Реагирование на события в JavaScript может быть организовано разными способами.

  • с помощью атрибута HTML: <body onload=”xyz();”>
  • с помощью атрибута onXXX, доступного в JavaScript: window.onload = xyz;

Однако в браузерах реализованы разные, конкурирующие механизмы обработки событий. Так, в Internet Explorer поддерживается присоединение событий к элементу с помощью метода attachEvent(). В этом случае имя события равнозначно имени атрибута HTML, поэтому, в частности, используется обозначение “onload”, хотя само событие называется “load”.

Во всех остальных браузерах поддерживается метод addEventListener(), являющийся составной частью модели W3C. В данном случае указывается имя события, поэтому вместо “onload” используется обозначение “load”.

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

<script type="text/javascript">
function eventHandler() {
  window.alert("Event fired!");
}

window.onload = function() {
  var button = document.getElementById("eventButton");
  if (button.addEventListener) {
    button.addEventListener("click", eventHandler, false);
  } else if (button.attachEvent) {
    button.attachEvent("onclick", eventHandler);
  }
};
</script>
<input type="button" id="eventButton" value="Click me!" />

Обработчики событий можно также удалить. Для этой цели в Internet Explorer служит метод detachEvent(), тогда как в остальных браузерах этот метод называется removeEventListener() в соответствии с моделью W3C.

Всплывание событий

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

<div><p><em>JavaScript</em> Phrasebook</p></div>

Если курсор мыши оказывается над текстом JavaScript, то событие mouseover сначала запускается в элементе <em>, а затем всплывает вверх до элементов <p> и <div>.

В конкурирующей модели W3C, которая поддерживается в браузерах Mozilla и Opera, события сначала погружаются вниз до целевого элемента, а затем всплывают вверх. Следовательно, в приведенном выше примере событие сначала опускается последовательно от элемента <div> до элементов <p> и <em>, а затем всплывает вверх до элементов <p> и <div>. При вводе процесса прослушивание событий в качестве третьего параметра функции addEventListener() можно указать порядок перехвата события: во время его погружения (логическое событие true) или всплывания (логическое событие false).

После того, как событие будет перехвачено, его погружение или всплывание можно прекратить. В Internet Explorer для этой цели свойству canselBubble присваивается логическое значение false:

window.event.canselBubble = false;

В модели W3C поддерживается метод stopPropagation():

e.stopPropagation();

Как видите, в Internet Explorer текущее событие всегда доступно посредством свойства window.event, тогда как в остальных браузерах событие автоматически воспринимается в качестве параметра (в данном случае e) функции прослушивания событий.

Ссылки по теме:

Динамическое формирование списка и таблицы

При использовании AJAX часто возникает задача динамического формирования элементов HTML-страницы с использованием DOM — на основе данных, полученных от сервера. Сегодня мы рассмотрим примеры составления списка и таблицы.

Формирование списка из данных JavaScript

В приведенном ниже коде функция createList() принимает в качестве аргумента массив и преобразует его в список:

<script language="JavaScript" type="text/javascript">
function createList(data) {
  var list = document.createElement("ul");
  for (var i = 0; i < data.length; i++) {
    var newItem = document.createElement("li");
    var newText = document.createTextNode(data[i]);
    newItem.appendChild(newText);
    list.appendChild(newItem);
  }
  return list;
}

window.onload = function() {
  var list = createList(["one", "two", "three", "four", "five"]);
  document.body.appendChild(list);
}
</script>

Формирование таблицы из данных JavaScript

Составить целую таблицу немного сложнее. Для этого прежде всего придется воспользоваться элементом <tbody>, а возможно, <tfoot> либо обоими элементами вместе. В противном случае в окне браузера Internet Explorer ничего не появится.

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

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

<script language="JavaScript" type="text/javascript">
function createTable(data) {
  var table = document.createElement("table");
  var thead = document.createElement("thead");
  var tr = document.createElement("tr");
  for (var i = 0; i < data[0].length; i++) {
    var th = document.createElement("th");
    var newText = document.createTextNode(data[0][i]);
    th.appendChild(newText);
    tr.appendChild(th);
  }
  thead.appendChild(tr);
  table.appendChild(thead);
 
  var tbody = document.createElement("tbody");
  for (var i = 1; i < data.length; i++) {
    var tr = document.createElement("tr");
    for (var j=0; j < data[i].length; j++) {
      var td = document.createElement("td");
      var newText = document.createTextNode(data[i][j]);
      td.appendChild(newText);
      tr.appendChild(td);
    }
    tbody.appendChild(tr);
  }

  table.appendChild(tbody);
  return table;
}

window.onload = function() {
  var table = createTable([
    ["1", "2", "3", "4", "5"],
    ["one", "two", "three", "four", "five"],
    ["un", "deux", "trois", "quatre", "cinq"],
    ["один", "два", "три", "четыре", "пять"]]);
  document.body.appendChild(table);
}
</script>

Создание экрана ожидания

Одним из самых существенных ограничений современных web-служб является время ожидания, когда нечто происходит, но в фоновом режиме, о чем следует непременно уведомить пользователей, иначе они не обратят внимания на происходящее. Для этой цели можно изменить вид курсора (cursor:wait) или же вывести надпись “ожидание” или “загрузка”, например при обработке вызова XMLHttpRequest. Web-cайт Google Mail стал одним из первых, где был использован данный прием.

При отправке асинхронного запроса на сервер в правом верхнем углу появляется экран загрузки (впрочем, его можно расположить в каком угодно месте). Как только от сервера возвратятся данные, экран загрузки становится невидимым.

Файл loading.html

<html>
<head>
<title>Loading...</title>
<script language="JavaScript" type="text/javascript" src="ajax.js"> </script>
</head>
<body>
<input type="button" value="Загрузить" onclick="loadData();" />
<span id="loading"
style="position: absolute; right:0; top:0; visibility: hidden; color: red;">
Загрузка...</span>
</body>
</html>

Файл ajax.js

var XMLHttp = getXMLHttp();

function loadData() {
  XMLHttp.open("GET", "delay.php", true);
  XMLHttp.onreadystatechange = handlerFunction;
  XMLHttp.send(null);
  document.getElementById("loading").style.visibility = "visible";
}

function handlerFunction() {
  if (XMLHttp.readyState == 4) {
    document.getElementById("loading").style.visibility = "hidden";
    window.alert("Ответ сервера: " + XMLHttp.responseText);
  }
}

function getXMLHttp() {
  if (window.XMLHttpRequest) {
    try {
      XMLHttp = new XMLHttpRequest();
    } catch (e) { }
  } else if (window.ActiveXObject) {
    try {
      XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) { }
    }
  }
  return XMLHttp;
}

Серверный скрипт delay.php

<?php
  sleep(10);
  echo 'результат запроса';
?>

Вместо надписи “Загрузка…” можно использовать какую-нибудь анимированную картинку:

Красивый индикатор загрузки можно загрузить с сайта http://www.ajaxload.info/: