Выбрать главу

      para.style.color = "red";

  });

  para.addEventListener("mouseout", function(event) {

    if (!isInside(event.relatedTarget, para))

      para.style.color = "";

  });

</script>

Функция isInside перебирает всех предков узла, пока не доходит до верха документа (и тогда узел равен null), или же не находит заданного ей родителя.

Должен добавить, что такой эффект достижим гораздо проще через псевдоселектор CSS под названием :hover, как показано ниже. Но когда при наведении вам надо делать что-то более сложное, чем изменение стиля узла, придётся использовать трюк с событиями "mouseover" и "mouseout".

<style>

  p:hover { color: red }

</style>

<p>Наведите мышь на этот <strong>параграф </strong>.</p>

События прокрутки

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

В примере в правом верхнем углу документа создаётся индикатор процесса, который заполняется по мере прокрутки элемента вниз.

<style>

  .progress {

    border: 1px solid blue;

    width: 100px;

    position: fixed;

    top: 10px; right: 10px;

  }

  .progress > div {

    height: 12px;

    background: blue;

    width: 0%;

  }

  body {

    height: 2000px;

  }

</style>

<div class="progress"><div></div></div>

<p>Scroll me...</p>

<script>

  var bar = document.querySelector(".progress div");

  addEventListener("scroll", function() {

    var max = document.body.scrollHeight - innerHeight;

    var percent = (pageYOffset / max) * 100;

    bar.style.width = percent + "%";

  });

</script>

Позиция элемента fixed означает почти то же, что absolute, но ещё и предотвращает прокручивание элемента вместе с остальным документом. Смысл в том, чтобы оставить наш индикатор в углу. Внутри него находится другой элемент, который изменяет размер, отражая текущий прогресс. Мы используем проценты вместо px для задания ширины, чтобы размер элемента изменялся относительно размера всего индикатора.

Глобальная переменная innerHeight даёт высоту окна, которую надо вычесть из полной высоты прокручиваемого элемента – при достижении конца элемента прокрутка заканчивается. (Также в дополнение к innerHeight есть переменная innerWidth). Поделив текущую позицию прокрутки pageYOffset на максимальную позицию прокрутки, и умножив на 100, мы получили процент для индикатора.

Вызов preventDefault не предотвращает прокрутку. Обработчик события вызывается уже после того, как прокрутка случилась.

События, связанные с фокусом

При получении элементом фокуса браузер запускает событие "focus". Когда он теряет фокус, запускается событие "blur".

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

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

<p>Имя: <input type="text" data-help="Ваше полное имя"></p>

<p>Возраст: <input type="text" data-help="Возраст в годах"></p>

<p id="help"></p>

<script>

  var help = document.querySelector("#help");

  var fields = document.querySelectorAll("input");

  for (var i = 0; i < fields.length; i++) {

    fields[i].addEventListener("focus", function(event) {

      var text = event.target.getAttribute("data-help");

      help.textContent = text;

    });

    fields[i].addEventListener("blur", function(event) {

      help.textContent = "";

    });

  }

</script>

Объект window получает события focus и blur, когда пользователь выделяет или убирает фокус с закладки браузера или окна браузера, в котором показан документ.

Событие загрузки

Когда заканчивается загрузка страницы, на объектах window и body запускается событие “load”. Это часто используется для планирования инициализирующих действий, которым необходим полностью построенный документ. Вспомните, что содержимое тегов <script> запускается сразу, как только тег встречается. Иногда это слишком рано – например, когда скрипту нужно что-то сделать с теми частями документа, которые находятся после тега <script>.