Javascript

Типы событий мыши

Мы можем разделить события мыши на две категории: «простые» и «комплексные».

Самые часто используемые простые события:

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

…Есть также несколько иных типов событий, которые мы рассмотрим позже.

Вызывается при , а затем над одним и тем же элементом, если использовалась левая кнопка мыши.
Вызывается двойным кликом на элементе.

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

Одно действие может вызвать несколько событий.

Например, клик мышью вначале вызывает , когда кнопка нажата, затем и , когда она отпущена.

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

Кликните на кнопку ниже, и вы увидите события. Также попробуйте двойной клик.

В окне теста ниже все события мыши записываются, и если задержка между ними более 1 секунды, то они разделяются горизонтальной чертой.

При этом мы также можем увидеть свойство , которое позволяет определить, какая кнопка мыши была нажата.

Обработчики событий

Последнее обновление: 1.11.2015

Встроенные обработчики

В прошлой теме были рассмотрены встроенные обработчики (inline event handler), которые определяются в коде элемента с
помощью атрибутов:

<div id="rect" onclick="handler(event)"></div>

Хотя этот подход прекрасно работает, но он имеет кучу недостатков:

  • Код html смешивается с кодом JavaScript, в связи с чем становится труднее разрабатывать, отлаживать и поддерживать приложение

  • Обработчики событий можно задать только для уже созданных на веб-странице элементов. Динамически создаваемые элементы в этом случае
    лишаются возможности обработки событий

  • К элементу для одного события может быть прикреплен только один обработчик

  • Нельзя удалить обработчик без изменения кода

Свойства обработчиков событий

Проблемы, которые возникают при использовании встроенных обработчиков, были призваны решить свойства обработчиков. Подобно тому, как у html-элементов
есть атрибуты для обработчиков, так и в коде javascript у элементов DOM мы можем получить свойства обработчиков, которые соответствуют атрибутам:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<style>
	#rect{
		width:50px;
		height:50px;
		background-color:blue;
	}
	</style>
</head>
<body>
<div id="rect"></div>
<script>
function handler(e){
	
	alert(e.type);
}
document.getElementById("rect").onclick = handler;
</script>
</body>
</html>

В итоге нам достаточно взять свойство и присвоить ему функцию, используемую в качестве обработчика. За счет
этого код html отделяется от кода javascript.

Стоит также отметить, что в обработчик события браузер автоматически передает объект Event, хранящий всю информацию о событии. Поэтому
также мы можем получить этот объект в функции обработчика в качестве параметра.

Слушатели событий

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

Для работы со слушателями событий в JavaScript есть объект EventTarget, который определяет методы
addEventListener() (для добавления слушателя) и removeEventListener()
для удаления слушателя. И поскольку html-элементы DOM тоже являются объектами EventTarget, то они также имеют эти методы. Фактически слушатели представляют те же функции обработчиков.

Метод принимает два параметра: название события без префикса on и функцию обработчика этого события. Например:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<style>
	#rect{
		width:50px;
		height:50px;
		background-color:blue;
	}
	</style>
</head>
<body>
<div id="rect"></div>
<script>
var rect = document.getElementById("rect");

rect.addEventListener("click", function (e) {
	alert(e.type);
});
</script>
</body>
</html>

То есть в данном случае опять же обрабатывается событие click. И также можно было бы в качестве второго параметра название функции:

function handler(e){
	
	alert(e.type);
}
var rect = document.getElementById("rect");

rect.addEventListener("click", handler);

Удаление слушателя аналогично добавлению:

rect.removeEventListener("click", handler);

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

var clicks = 0;
function handlerOne(e){
	
	alert(e.type);
}
function handlerTwo(e){
	
	clicks++;
	var newNode = document.createElement("p");
	newNode.textContent = "произошло нажатие " + clicks;
	document.body.appendChild(newNode);
}
var rect = document.getElementById("rect");
// прикрепляем первый обработчик
rect.addEventListener("click", handlerOne);
// прикрепляем второй обработчик
rect.addEventListener("click", handlerTwo);

НазадВперед

JS Уроки

JS HOMEJS IntroductionJS Where ToJS OutputJS StatementsJS SyntaxJS CommentsJS VariablesJS OperatorsJS ArithmeticJS AssignmentJS Data TypesJS FunctionsJS ObjectsJS ScopeJS EventsJS StringsJS String MethodsJS NumbersJS Number MethodsJS ArraysJS Array MethodsJS Array SortJS Array IterationJS DatesJS Date FormatsJS Date Get MethodsJS Date Set MethodsJS MathJS RandomJS BooleansJS ComparisonsJS ConditionsJS SwitchJS Loop ForJS Loop WhileJS BreakJS Type ConversionJS BitwiseJS RegExpJS ErrorsJS DebuggingJS HoistingJS Strict ModeJS this KeywordJS Style GuideJS Best PracticesJS MistakesJS PerformanceJS Reserved WordsJS VersionsJS Version ES5JS Version ES6JS JSON

Пользовательские события

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

У второго аргумента-объекта есть дополнительное свойство , в котором можно указывать информацию для передачи в событие.

Например:

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

Кроме того, класс события описывает, что это за событие, и если оно не браузерное, а пользовательское, то лучше использовать , чтобы явно об этом сказать.

Прекращение всплытия

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

Но любой промежуточный обработчик может решить, что событие полностью обработано, и остановить всплытие.

Для остановки всплытия нужно вызвать метод .

Например, здесь при клике на кнопку обработчик не сработает:

event.stopImmediatePropagation()

Если у элемента есть несколько обработчиков на одно событие, то даже при прекращении всплытия все они будут выполнены.

То есть, препятствует продвижению события дальше, но на текущем элементе все обработчики отработают.

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

Не прекращайте всплытие без необходимости!

Всплытие – это удобно. Не прекращайте его без явной нужды, очевидной и архитектурно прозрачной.

Зачастую прекращение всплытия создаёт свои подводные камни, которые потом приходится обходить.

Например:

  1. Мы делаем меню. Оно обрабатывает клики на своих элементах и делает для них . Вроде бы, всё работает.
  2. Позже мы решили отслеживать все клики в окне, для какой-то своей функциональности, к примеру, для статистики – где вообще у нас кликают люди. Например, Яндекс.Метрика так делает, если включить соответствующую опцию.
  3. Над областью, где клики убиваются , статистика работать не будет! Получилась «мёртвая зона».

Проблема в том, что убивает всякую возможность отследить событие сверху, а это бывает нужно для реализации чего-нибудь «эдакого», что к меню отношения совсем не имеет.

В завершение. А зачем использовать делегирование событий?

Без делегирования событий, вам бы пришлось перепривязывать событие по клику на каждый новый , добавленный на страницу. Делать такую писанину довольно проблематично и обременительно. Во первых, такой подход значительно увеличит количество слушателей событий на вашей странице и их большое количество увеличит объем памяти, потребляемое вашей страницей. Что приведет к снижению производительности, что само по себе уже плохо. Во вторых, могут произойти проблемы с утечкой памяти из-за циклической привязки и отвязки слушателей событий, и удаления элементов из DOM. Но это уже выходит за рамки данной статьи.

Как же пофиксить эту проблему?

Делегированием событий.

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

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

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

Давайте прикрепим слушатель событий:

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

 это отсылка к объекту, на котом сработало событие. Или другими словами, он указывает на HTML элемент на котором сработало событие.

Событие в нашем случае это клик. Объект на котором отработало событие это .

**  рассматривается, как часть объекта  — поэтому мы видимо их обоих**

Восходящая маршрутизация событий или захват событий?

Существует два способа распространения событий в DOM HTML, восходящей и захватывающей.

Распространение событий — это способ определения порядка элементов при возникновении события.
Если у вас есть элемент <p> внутри элемента <div>, и пользователь щелкает элемент <p>, то какой элемент «Click» должен обрабатываться первым?

При восходящей маршрутизации внутреннее событие самого элемента обрабатывается первым, а затем внешним:
сначала обрабатывается событие Click элемента <p>, затем событие Click элемента <div>.

При захвате внешнего самого элемента сначала обрабатывается событие, а затем внутреннее:
событие Click элемента <div> будет обработано первым, а затем <p> событие Click элемента.

С помощью метода addEventListener () можно указать тип распространения, используя параметр «useCapture присвоено»:

addEventListener(event, function, useCapture);

Значение по умолчанию — false, которое будет использовать восходящее распространение, если значение установлено в true, событие использует распространение захвата.

Пример

document.getElementById(«myP»).addEventListener(«click», myFunction, true);
document.getElementById(«myDiv»).addEventListener(«click», myFunction, true);

Движение мыши

Каждый раз, когда перемещается курсов мыши, срабатывает событие «mousemove» из набора JavaScript mouse events. Оно может быть использовано для отслеживания положения мыши. Это применяется при реализации возможности перетаскивания элементов мышью.

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

<p>Потяните за край панели, чтобы изменить ее ширину:</p>
<div style="background: orange; width: 60px; height: 20px">
</div>
<script>
  var lastX; // Отслеживает последнюю позицию X мыши
  var rect = document.querySelector("div");
  rect.addEventListener("mousedown", function(event) {
    if (event.which == 1) {
      lastX = event.pageX;
      addEventListener("mousemove", moved);
      event.preventDefault(); // Предотвращает выделение
    }
  });

  function buttonPressed(event) {
    if (event.buttons == null)
      return event.which != 0;
    else
      return event.buttons != 0;
  }
  function moved(event) {
    if (!buttonPressed(event)) {
      removeEventListener("mousemove", moved);
    } else {
      var dist = event.pageX - lastX;
      var newWidth = Math.max(10, rect.offsetWidth + dist);
      rect.style.width = newWidth + "px";
      lastX = event.pageX;
    }
  }
</script>

Обратите внимание, что обработчик «mousemove» зарегистрирован для всего окна. Даже если во время изменения размеров мышь выходит за пределы панели, мы все равно обновляем ширину панели и прекращаем JavaScript touch events, когда клавиша мыши была отпущена

Мы должны прекратить изменение размера панели, когда пользователь отпускает клавишу мыши. К сожалению, не все браузеры устанавливают для событий «mousemove» свойство which. Существует стандартное свойство buttons, которое предоставляет аналогичную информацию, но оно также поддерживается не во всех браузерах. К счастью, все основные браузеры поддерживают что-то одно: либо buttons, либо which. Функция buttonPressed в приведенном выше примере сначала пытается использовать свойство buttons, и, если оно не доступно, переходит к which.

Когда курсор мыши наводится или покидает узел, запускаются события «mouseover» или «mouseout«. Они могут использоваться для создания эффектов при наведении курсора мыши, вывода какой-нибудь подписи или изменения стиля элемента.

Чтобы создать такой эффект, недостаточно просто начать его отображение при возникновении события «mouseover» и завершить после события «mouseout«. Когда мышь перемещается от узла к одному из его дочерних элементов, для родительского узла происходит событие «mouseout«. Хотя указатель мыши не покинул диапазон распространения узла.

Что еще хуже, эти JavaScript event распространяются так же, как и другие события. Когда мышь покидает один из дочерних узлов, для которого зарегистрирован обработчик, возникнет событие «mouseout«.

Чтобы обойти эту проблему, можно использовать свойство объекта события relatedTarget. В случае возникновения события «mouseover» оно указывает, на какой элемент был наведен курсор мыши до этого. А в случае возникновения «mouseout» — к какому элементу перемещается указатель. Мы будем изменять эффект наведения мыши только, когда relatedTarget находится вне нашего целевого узла.

В этом случае мы изменяем поведение, потому что курсор мыши был наведен на узел из-за его пределов (или наоборот):

<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>
<script>
  var para = document.querySelector("p");
  function isInside(node, target) {
    for (; node != null; node = node.parentNode)
      if (node == target) return true;
  }
  para.addEventListener("mouseover", function(event) {
    if (!isInside(event.relatedTarget, para))
      para.style.color = "red";
  });
  para.addEventListener("mouseout", function(event) {
    if (!isInside(event.relatedTarget, para))
      para.style.color = "";
  });
</script>

Функция isInside отслеживает родительские связи заданного узла или пока не будет достигнута верхняя часть документа (когда node равен нулю). Либо не будет найден родительский элемент, который нам нужен.

Эффект наведения гораздо проще создать с помощью псевдоселектора CSS :hover, как показано в следующем примере. Но когда эффект наведения предполагает что-то более сложное, чем просто изменение стиля целевого узла, тогда нужно использовать прием с использованием событий «mouseover» и «mouseout» (JavaScript mouse events):

<style>
  p:hover { color: red }
</style>
<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>

Действие браузера по умолчанию

Браузер имеет своё собственное поведение по умолчанию для различных событий.

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

element.onclick = function(event) {
    event = event || window.event 

    if (event.preventDefault) {
        // Вариант стандарта W3C: 
        event.preventDefault()
    } else {
        // Вариант Internet Explorer:
        event.returnValue = false
    }
}

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

..
event.preventDefault ? event.preventDefault() : (event.returnValue=false)
...

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

Например, при фокусировке на ссылке — браузер выделяет ее пунктирной рамочкой.
Это действие выполняется до события , поэтому отменить выделение в обработчике нельзя.

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

Код примера:

var a = document.getElementById('my-focus-a')
a.onfocus = a.onclick = function(e) {
    e = e || window.event
    // другая кроссбраузерная запись остановки события
    e.preventDefault ? e.preventDefault() : (e.returnValue=false)
}

Применение делегирования: действия в разметке

Есть и другие применения делегирования.

Например, нам нужно сделать меню с разными кнопками: «Сохранить (save)», «Загрузить (load)», «Поиск (search)» и т.д. И есть объект с соответствующими методами , , … Как их состыковать?

Первое, что может прийти в голову – это найти каждую кнопку и назначить ей свой обработчик среди методов объекта. Но существует более элегантное решение. Мы можем добавить один обработчик для всего меню и атрибуты для каждой кнопки в соответствии с методами, которые они вызывают:

Обработчик считывает содержимое атрибута и выполняет метод. Взгляните на рабочий пример:

Обратите внимание, что метод в строке, отмеченной звёздочкой , привязывается к контексту текущего объекта

Это важно, т.к. иначе внутри него будет ссылаться на DOM-элемент (), а не на объект , и будет не тем, что нам нужно

иначе внутри него будет ссылаться на DOM-элемент (), а не на объект , и будет не тем, что нам нужно.

Так что же даёт нам здесь делегирование?

  • Не нужно писать код, чтобы присвоить обработчик каждой кнопке. Достаточно просто создать один метод и поместить его в разметку.
  • Структура HTML становится по-настоящему гибкой. Мы можем добавлять/удалять кнопки в любое время.

Мы также можем использовать классы , , но подход с использованием атрибутов является более семантичным. Их можно использовать и для стилизации в правилах CSS.

More Examples

Example

You can also refer to an external «named» function.

This example demonstrates how to execute a function when a user clicks on a <button> element:

document.getElementById(«myBtn»).addEventListener(«click», myFunction);function myFunction() {  document.getElementById(«demo»).innerHTML = «Hello World»;
}

Example

You can add many events to the same element, without overwriting existing
events.

This example demonstrates how to add two click events on the same <button> element:

document.getElementById(«myBtn»).addEventListener(«click», myFunction);document.getElementById(«myBtn»).addEventListener(«click», someOtherFunction);

Example

You can add events of different types to the same element.

This example demonstrates how to add many events on the same <button> element:

document.getElementById(«myBtn»).addEventListener(«mouseover», myFunction);document.getElementById(«myBtn»).addEventListener(«click», someOtherFunction);
document.getElementById(«myBtn»).addEventListener(«mouseout», someOtherFunction);

Example

When passing parameter values, use an «anonymous function» that calls the
specified function with the parameters:

document.getElementById(«myBtn»).addEventListener(«click», function() {  myFunction(p1, p2);});

Example

Change the background color of a <button> element:

document.getElementById(«myBtn»).addEventListener(«click», function() {  this.style.backgroundColor = «red»;});

Example

Using the optional useCapture parameter to demonstrate the
difference between bubbling and capturing:

document.getElementById(«myDiv»).addEventListener(«click», myFunction, true);

Example

Using the removeEventListener() method to remove an event handler that has
been attached with the addEventListener() method:

// Attach an event handler to <div>document.getElementById(«myDIV»).addEventListener(«mousemove», myFunction);// Remove the event handler from <div>document.getElementById(«myDIV»).removeEventListener(«mousemove», myFunction);

Example

For browsers that don’t support the addEventListener() method, you can use
the attachEvent() method.

This example demonstrates a cross-browser solution:

var x = document.getElementById(«myBtn»);if (x.addEventListener) {                    // For all major browsers, except IE 8 and earlier
  x.addEventListener(«click», myFunction);} else if (x.attachEvent) {                  // For IE 8 and earlier versions
  x.attachEvent(«onclick», myFunction);}

Задачи

1. Скрыть элемент по нажатию кнопки с классом spoiler-trigger

Написать JavaScript код, который при нажатии на кнопку будет скрывать элемент, расположенный сразу за ней. При этом на странице таких кнопок может быть несколько.

<style>
.hide {
  display: none;
}
</style>

<button class="spoiler-trigger">Скрыть/показать контент</button>
<div>...</div>
...
<button class="spoiler-trigger">Скрыть/показать контент</button>
<div>...</div>

Решение

2. Создать выпадающее меню

Имеется следующая разметка (стили добавлять не нужно, они имеются в примере):

<div class="dropdown">
  <button class="dropdown__trigger">Меню</button>
  <div class="dropdown__content">
    <a href="#">Ссылка 1</a>
    <a href="#">Ссылка 2</a>
    <a href="#">Ссылка 3</a>
  </div>
</div>

Необходимо написать скрипт, который будет при нажатии на кнопку () переключался класс у элемента :

Решение

Дробление

Некоторые типы событий могут запускаться много раз в течение короткого периода времени (например, «mousemove» и javascript scroll event). При обработке таких событий, нужно быть осторожным, чтобы это не происходило очень долго, иначе обработчик будет выполнять действие столько времени, что взаимодействие с документом станет медленным и скачкообразным.

Если нужно сделать что-то нестандартное в таком обработчике, можно использовать setTimeout, чтобы быть уверенными, что это не растянется слишком надолго. Это обычно называют дроблением события. Существует несколько отличающихся друг от друга подходов к дроблению.

В первом примере мы хотим сделать что-то, когда пользователь печатает. Но не хотим делать это после каждого события нажатия клавиши. Когда пользователь быстро печатает, нужно подождать, пока не произойдет пауза. Вместо немедленного выполнения действия в обработчике события мы устанавливаем задержку. Мы также очищаем предыдущую задержку (если таковая имеется). Если события происходят через короткие интервалы времени (меньше, чем установленная нами задержка), то задержка от предыдущего события отменяется:

<textarea>Напечатайте что-нибудь здесь...</textarea>
<script>
  var textarea = document.querySelector("textarea");
  var timeout;
  textarea.addEventListener("keydown", function() {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
      console.log("Вы перестали печатать.");
    }, 500);
  });
</script>

Передача неопределенного значения для clearTimeout или его вызов для задержки, которая уже запущена, не даст никакого результата. Нам больше не нужно быть осторожными относительно того, когда его вызывать, мы просто делаем это для каждого события.

Можно использовать иной сценарий, если нужно разделить ответы небольшим промежутком времени. Но чтобы при этом они запускались во время серии событий, а не только после нее. Например, можно отправлять в ответ на события «mousemove» (JavaScript mouse events) текущие координаты мыши, но только через каждые 250 миллисекунд:

<script>
  function displayCoords(event) {
    document.body.textContent =
      "мышь находится в точке " + event.pageX + ", " + event.pageY;
  }

  var scheduled = false, lastEvent;
  addEventListener("mousemove", function(event) {
    lastEvent = event;
    if (!scheduled) {
      scheduled = true;
      setTimeout(function() {
        scheduled = false;
        displayCoords(lastEvent);
      }, 250);
    }
  });
</script>

Что такое событие?

Событие – это определённый сигнал от браузера. Он сообщает нам о том, что что-то произошло.

Например: щелчок мыши, нажатие клавиши на клавиатуре, изменение размера области просмотра, завершение загрузки документа и т.д.

При этом сигнал всегда связан с объектом. Подавать сигналы могут различные объекты: , , DOM-элементы и т.д.

Список некоторых событий и их название:

  • – завершение загрузки DOM;
  • – клик (нажатие левой кнопки мыши, на устройствах с сенсорным управлением возникает при касании);
  • – нажатие клавиши на клавиатуре;
  • – изменение размеров документа;
  • – окончание изменения значения в поле ввода.

Заключение

Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не имеем прямого контроля. Для регистрации такого обработчика используется метод addEventListener.

Каждое событие относится к определенному типу («keydown«, «focus» и так далее), который идентифицирует его. Большинство событий вызывается для конкретного элемента DOM, а затем распространяются на родительские узлы элемента. Это позволяет обработчикам, связанным с этими элементами, обрабатывать их.

Когда вызывается обработчик, ему передается объект события с дополнительной информацией о действии. Этот объект также содержит методы, позволяющие остановить дальнейшее распространение события (stopPropagation) или предотвратить обработку события браузером по умолчанию (preventDefault).

Нажатие клавиш порождает события «keydown«, «keypress» и «keyup«. Нажатие мыши порождает события «mousedown«, «mouseup» и «click«. Перемещение мыши — «mousemove«, «mouseenter» и «mouseout«.

JavaScript scroll event можно определить с помощью события «scroll«, а смена фокуса — «focus» и «blur«. После завершения загрузки документа для окна возникает событие «load«.

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

Данная публикация является переводом статьи «Handling Events» , подготовленная редакцией проекта.

Итого

Делегирование событий – это здорово! Пожалуй, это один из самых полезных приёмов для работы с DOM.

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

Алгоритм:

  1. Вешаем обработчик на контейнер.
  2. В обработчике проверяем исходный элемент .
  3. Если событие произошло внутри нужного нам элемента, то обрабатываем его.

Зачем использовать:

  • Упрощает процесс инициализации и экономит память: не нужно вешать много обработчиков.
  • Меньше кода: при добавлении и удалении элементов не нужно ставить или снимать обработчики.
  • Удобство изменений DOM: можно массово добавлять или удалять элементы путём изменения и ему подобных.

Конечно, у делегирования событий есть свои ограничения:

Во-первых, событие должно всплывать. Некоторые события этого не делают. Также, низкоуровневые обработчики не должны вызывать .
Во-вторых, делегирование создаёт дополнительную нагрузку на браузер, ведь обработчик запускается, когда событие происходит в любом месте контейнера, не обязательно на элементах, которые нам интересны

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector