Приём проектирования "поведение"

Шаблон проектирования «поведение» (behavior) позволяет задавать хитрые обработчики на элементе декларативно, установкой специальных HTML-атрибутов и классов.

Описание

Приём проектирования «поведение» состоит из двух частей:

  1. Элементу ставится атрибут, описывающий его поведение.
  2. При помощи делегирования ставится обработчик на документ, который ловит все клики и, если элемент имеет нужный атрибут, производит нужное действие.

Пример

Например, добавим «поведение», которое всем элементам, у которых стоит атрибут data-counter, будет при клике увеличивать значение на 1:

Счётчик:
<button data-counter>1</button>
Ещё счётчик:
<button data-counter>2</button>

<script>
  document.onclick = function(event) {
    if (!event.target.hasAttribute('data-counter')) return;

    var counter = event.target;

    counter.innerHTML++;
  };
</script>

Если запустить HTML-код выше, то при клике на каждую кнопку – её значение будет увеличиваться.

Конечно, нам важны не счётчики, а общий подход, который они демонстрируют.

Элементов data-counter может быть сколько угодно. Новые могут добавляться в HTML в любой момент. При помощи делегирования мы, фактически, добавили новый «псевдо-стандартный» атрибут в HTML, который добавляет элементу новую возможность («поведение»).

Ещё пример

Добавим ещё поведение.

Сделаем так, что при клике на элемент с атрибутом data-toggle-id будет скрываться/показываться элемент с заданным id:

<button data-toggle-id="subscribe-mail">
  Показать форму подписки
</button>

<form id="subscribe-mail" hidden>
  Ваша почта: <input type="email">
</form>

<script>
  document.onclick = function(event) {
    var target = event.target;

    var id = target.getAttribute('data-toggle-id');
    if (!id) return;

    var elem = document.getElementById(id);

    elem.hidden = !elem.hidden;
  };
</script>

Ещё раз заметим, что мы сделали. Теперь для того, чтобы добавить скрытие-раскрытие любому элементу – даже не надо знать JavaScript, можно просто написать атрибут data-toggle-id.

Это бывает очень удобно – не нужно писать JavaScript-код для каждого элемента, который должен служить такой кнопкой. Просто используем поведение.

Обратите внимание: обработчик поставлен на document, клик на любом элементе страницы пройдёт через него, так что поведение определено глобально.

Не только атрибут

Для своих целей мы можем использовать в HTML любые атрибуты, но стандарт рекомендует для своих целей называть атрибуты data-*.

В обработчике document.onclick мы могли бы проверять не атрибут, а класс или что-то ещё, но с атрибутом – проще и понятнее всего.

Также для добавления обработчиков на document рекомендуется использовать addEventListener, чтобы можно было добавить более одного обработчика для типа события.

Итого

Шаблон «поведение» удобен тем, что сколь угодно сложное JavaScript-поведение можно «навесить» на элемент одним лишь атрибутом. А можно – несколькими атрибутами на связанных элементах.

Здесь мы рассмотрели базовый пример, который можно как угодно модифицировать и масштабировать. Важно не переусердствовать.

Приём разработки «поведение» рекомендуется использовать для расширения возможностей разметки, как альтернативу мини-фрагментам JavaScript.

Задачи

важность: 5

При наведении мыши на элемент, на нём возникает событие mouseover, при удалении мыши с элемента – событие mouseout.

Зная это, напишите JS-код, который будет делать так, что при наведении на элемент, если у него есть атрибут data-tooltip – над ним будет показываться подсказка с содержимым этого атрибута.

Например, две кнопки:

<button data-tooltip="подсказка длиннее, чем элемент">Короткая кнопка</button>
<button data-tooltip="HTML<br>подсказка">Ещё кнопка</button>

Результат в ифрейме с документом:

В этой задаче можно полагать, что в элементе с атрибутом data-tooltip – только текст, то есть нет подэлементов.

Детали оформления:

  • Подсказка должна появляться при наведении на элемент, по центру и на небольшом расстоянии сверху. При уходе курсора с элемента – исчезать.
  • Текст подсказки брать из значения атрибута data-tooltip. Это может быть произвольный HTML.
  • Оформление подсказки должно задаваться CSS.
  • Подсказка не должна вылезать за границы экрана, в том числе если страница частично прокручена. Если нельзя показать сверху – показывать снизу элемента.

Важно: нужно использовать приём разработки «поведение», то есть поставить обработчик (точнее два) на document, а не на каждый элемент.

Плюс этого подхода – динамически добавленные в DOM позже элементы автоматически получат этот функционал.

Открыть песочницу для задачи.

Карта учебника

Комментарии

перед тем как писать…
  • Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
  • Для одной строки кода используйте тег <code>, для нескольких строк кода — тег <pre>, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)
  • Если что-то непонятно в статье — пишите, что именно и с какого места.