Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Эта страница была переведена с английского языка силами сообщества. Вы тоже можете внести свой вклад, присоединившись к русскоязычному сообществу MDN Web Docs.

EventTarget: метод addEventListener()

BaselineWidely available *

Примечание: Эта возможность доступна вWeb Workers.

МетодaddEventListener() интерфейсаEventTarget устанавливает функцию, которая будет вызываться каждый раз, когда указанное событие будет достигать цели.

Наиболее распространёнными целями являютсяElement и его дочерние элементы,Document иWindow, но целью может быть любой объект, поддерживающий события (например,IDBRequest).

Примечание:МетодaddEventListener() являетсярекомендованным способ регистрации обработчиков событий. Его преимущества состоят в следующем::

  • Позволяет добавлять более одного обработчика для события. Это очень полезно для использования в библиотеках, модулях JavaScript и тех случаях, когда требуется работать с другими библиотеками или расширениями.
  • В отличие от использования свойств видаonXYZ, позволяет он даёт более точный контроль над фазой активации слушателя (захват или всплытие).
  • Работает на всех целях событий, а не только на элементах HTML и SVG.

МетодaddEventListener() работает, добавляя функцию или объект, который реализует функциюhandleEvent(), в список слушателей события для указанного типа целиEventTarget, на которой он был вызван.Если функция или объект уже присутствует в списке слушателей для этой цели, то повторного добавления не будет.

Примечание:Если конкретная анонимная функция находится в списке слушателей событий, зарегистрированных для определённой цели, а далее в коде идентичная анонимная функция указана в вызовеaddEventListener, вторая функциябудет добавлена ​​в список слушателей событий для этой цели.

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

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

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

Синтаксис

js
addEventListener(type, listener)addEventListener(type, listener, options)addEventListener(type, listener, useCapture)

Параметры

type

Чувствительная к регистру строка, представляющаятип обрабатываемого события.

listener

Объект, реализующий интерфейсEvent, который принимает уведомление, когда событие указанного типа произошло. Это должен бытьnull, объект с методомhandleEvent() илифункция. Посмотрите также разделФункция обратного вызова для обработчика событий.

optionsНеобязательный

Объект, который определяет характеристики слушателя событие:

captureНеобязательный

Логическое значение, указывающее, что события указанного типа будут отправлены зарегистрированному слушателюlistener перед отправкой любойEventTarget ниже в DOM-дереве. Если не указано, то по умолчаниюfalse.

onceНеобязательный

Логическое значение, указывающее, чтоlistener должен быть вызван только один раз после добавления. Еслиtrue, тоlistener будет автоматически удалён после вызова. Если не указано, то по умолчаниюfalse.

passiveНеобязательный

Логическое значение, указывающее, чтоlistener никогда не вызоветpreventDefault(). Если пассивный слушатель вызываетpreventDefault(), ничего не произойдет, и может быть сгенерировано предупреждение в консоли.

Если не указано, то по умолчаниюfalse за исключением того, что в браузерах, отличных от Safari, для событийwheel,mousewheel,touchstart andtouchmove по умолчанию принимается значениеtrue. Смотрите также разделИспользование пассивных слушателей.

signalНеобязательный

AbortSignal. Слушатель будет удалён при вызове методаabort() данного объектаAbortSignal. Если не указано, то со слушателем не будет связан никакойAbortSignal.

useCaptureНеобязательный

Логическое значение, указывающее, будут ли события этого типа отправлены зарегистрированному слушателюlistenerперед отправкой в любойEventTarget ниже в DOM-дереве. События, которые всплывают вверх по дереву, не вызовут слушателя, настроенного для использования захвата. Всплытие событий и захват — это два способа распространения событий, которые происходят в элементе, который вложен в другой элемент, и обоих элементов зарегистрирован обработчик этого события. Режим распространения событий определяет порядок, в котором элементы получают событие. Подробное объяснение смотрите вDOM Level 3 Events иПорядок событий в JavaScript.Если не указано,useCapture по умолчанию имеет значениеfalse.

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

wantsUntrustedНеобязательныйНе стандартно

Параметр, специфичный для Firefox (Gecko). Еслиtrue, слушатель получает синтетические события, отправленные веб-контентом. По умолчаниюfalse для браузераchrome иtrue для обычных веб-страниц. Этот параметр полезен для кода, обнаруженного в надстройках, а также для самого браузера.

Возвращаемое значение

Нет (undefined).

Примечания по использованию

Функция обратного вызова для обработчика событий

Слушатель события может быть указан как функция обратного вызова или как объект, методhandleEvent() которого служит функцией обратного вызова.

Сама функция обратного вызова имеет те же параметры и возвращаемое значение, что и методhandleEvent(), то есть функция обратного вызова принимает один параметр — объект на основеEvent, описывающий произошедшее событие, и она ничего не возвращает.

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

js
function handleEvent(event) {  if (event.type === "fullscreenchange") {    /* обработка изменения полноэкранного режима */  } else {    /* обработка ошибки при изменении полноэкранного режима */  }}

Использование пассивных слушателей

Если событие имеет действие по умолчанию (например, событиеwheel, которое по умолчанию прокручивает контейнер), то браузер, как правило, не может запустить его до завершения работы слушателя события, поскольку он не знает заранее, может ли слушатель события отменить действие по умолчанию, вызвавEvent.preventDefault(). Если слушатель события выполняется слишком долго, это может привести к заметной задержке, известной также как «jank», прежде чем действие по умолчанию будет выполнено.

Устанавливая опциюpassive вtrue, слушатель событий объявляет, что он не отменит действие по умолчанию, поэтому браузер может немедленно запустить действие по умолчанию, не дожидаясь завершения слушателя. Если слушатель это сделает, а затем вызоветEvent.preventDefault(), это не даст никакого эффекта.

СпецификацияaddEventListener() определяет значение по умолчанию для параметраpassive какfalse. Однако, чтобы реализовать преимущества производительности прокрутки в устаревшем коде, современные браузеры изменили значение по умолчанию параметраpassive наtrue для событийwheel,mousewheel,touchstart иtouchmove на узлах уровня документаWindow,Document иDocument.body. Это не позволяет слушателю событийотменять событие, поэтому он не может блокировать отрисовку, пока пользователь прокручивает страницу.

По этой причине для переопределения этого поведение и чтобы убедиться, что параметрpassive имеет значениеfalse, необходимо явно задать параметру значениеfalse вместо того, чтобы полагаться на значение по умолчанию.

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

Смотрите разделУлучшение производительности прокрутки с помощью пассивных слушателей с примером использования пассивных слушателей.

Примеры

Добавление простого обработчика

Эти примеры демонстрируют как использоватьaddEventListener() для наблюдения за щелчками мышкой по элементу.

HTML Содержимое

html
<table>  <tr>    <td>один</td>  </tr>  <tr>    <td>два</td>  </tr></table>

JavaScript Содержимое

js
// Функция изменяет содержимое t2function modifyText() {  var t2 = document.getElementById("t2");  if (t2.firstChild.nodeValue == "три") {    t2.firstChild.nodeValue = "два";  } else {    t2.firstChild.nodeValue = "три";  }}// Добавляет обработчика событий для таблицыvar el = document.getElementById("outside");el.addEventListener("click", modifyText, false);

В примере выше,modifyText() регистрирует обработчика для события click, используяaddEventListener(). Клик в любом месте таблицы будет поднимать обработчик и запускатьmodifyText().

Результат

Если вам нужно передать параметры в обработчик, вы можете использовать анонимные функции.

Обработчик события с анонимной функцией

HTML Содержимое

html
<table>  <tr>    <td>один</td>  </tr>  <tr>    <td>два</td>  </tr></table>

JavaScript Содержимое

js
// Функция, изменяющая содержание t2function modifyText(new_text) {  var t2 = document.getElementById("t2");  t2.firstChild.nodeValue = new_text;}// Функция, добавляющая обработчик к таблицеel = document.getElementById("outside");el.addEventListener(  "click",  function () {    modifyText("четыре");  },  false,);

Обратите внимание, что addEvenListener - это анонимная функция, которая инкапсулирует код, который, в свою очередь, может отправлять параметры функции modifyText(), которая отвечает за фактический ответ на событие.

Результат

Обработчик события со стрелочной функцией

HTML

html
<table>  <tr>    <td>one</td>  </tr>  <tr>    <td>two</td>  </tr></table>

JavaScript

js
// Function to change the content of t2function modifyText(new_text) {  var t2 = document.getElementById("t2");  t2.firstChild.nodeValue = new_text;}// Add event listener to table with an arrow functionvar el = document.getElementById("outside");el.addEventListener(  "click",  () => {    modifyText("four");  },  false,);

Результат

Обратите внимание: несмотря на то, что анонимные и стрелочные функции схожи, они имеют разные значенияthis.

Примечания

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

addEventListener — это способ зарегистрировать обработчик события, описанный в документации W3C DOM. Вот список преимуществ его использования:

  • Позволяет добавлять множество обработчиков для одного события. Это особенно полезно дляDHTML библиотек илиMozilla extensions, которые должны работать в условиях использования сторонних библиотек/расширений.
  • Предоставляет точный контроль фазы срабатывания(вызова) обработчика (захват или всплытие).
  • Срабатывает на любом DOM-элементе, а не только на HTML-элементах.

Ниже описан другой,более старый способ регистрации обработчиков.

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

ЕслиEventListener добавлен кEventTarget во время обработки события, он не будет вызван текущими действиями, но может быть вызван на более поздней стадии обработки события, при восходящей обработке.

Несколько одинаковых обработчиков события

Если зарегистрировано несколько одинаковыхEventListener на одномEventTarget с одинаковыми параметрами, дублирующиеся обработчики игнорируются. Так как одинаковые обработчики игнорируются, не требуется удалять их вручную с помощью методаremoveEventListener.

Значениеthis в обработчике

Обычно желательно передавать элемент, на котором сработал обработчик события, например, при использовании обобщённых обработчиков для схожих элементов. При добавлении функции при помощиaddEventListener() значение переменнойthis меняется — заметьте, что значениеthis передаётся в функцию от вызывающего объекта.

В примере выше значение переменнойthis внутриmodifyText() при вызове событием клика равно таблице 't'. Это противоположно поведению, которое возникает, если обработчик добавлен в HTML-разметке:

html
<table>  . . .</table>

Значение переменнойthis внутриmodifyText() при вызове событием клика будет равно ссылке на глобальный (window) объект (илиundefined при использованииstrict mode)

Примечание:В JavaScript 1.8.5 введён методFunction.prototype.bind(), который позволяет указать значение, которое должно быть использовано для всех вызовов данной функции. Он позволяет вам легко обходить ситуации, в которых не ясно, чему будет равно this, в зависимости от того, в каком контексте будет вызвана ваша функция. заметьте, также, что вам будет необходимо иметь внешнюю ссылку на обработчик, чтобы вы могли удалить его позже.

Пример с использованиемbind и без него:

js
var Something = function (element) {  this.name = "Something Good";  this.onclick1 = function (event) {    console.log(this.name); // undefined, так как this является элементом  };  this.onclick2 = function (event) {    console.log(this.name); // 'Something Good', так как в this передано значение объекта Something  };  element.addEventListener("click", this.onclick1, false);  element.addEventListener("click", this.onclick2.bind(this), false); // Trick};

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

js
var Something = function (element) {  this.name = "Something Good";  this.handleEvent = function (event) {    console.log(this.name); // 'Something Good', так как this является объектом Something    switch (event.type) {      case "click":        // код обработчика...        break;      case "dblclick":        // код обработчика...        break;    }  };  // В этом случае обработчики хранятся в this, а не в this.handleEvent  element.addEventListener("click", this, false);  element.addEventListener("dblclick", this, false);  // Вы можете напрямую удалять обработчики  element.removeEventListener("click", this, false);  element.removeEventListener("dblclick", this, false);};

Наследство Internet Explorer и attachEvent

В Internet Explorer младше 9 версии, вы можете использоватьattachEvent вместо стандартногоaddEventListener. Для поддержки IE, пример выше может быть модифицирован следующим образом:

js
if (el.addEventListener) {  el.addEventListener("click", modifyText, false);} else if (el.attachEvent) {  el.attachEvent("onclick", modifyText);}

УattachEvent есть недостаток:this будет ссылаться на объектwindow, а не на элемент, на котором он был вызван.

Совместимость

Вы можете обойти методыaddEventListener,removeEventListener,Event.preventDefault иEvent.stopPropagation не поддерживаемы в IE 8 используя следующий код в начале вашего скрипта. Этот код поддерживает использованиеhandleEvent и событияDOMContentLoaded.

Примечание:ПараметрuseCapture не поддерживается, так как IE 8 не имеет альтернативного метода для этого. Также заметьте, что следующий код только добавляет поддержку IE 8. Также, он работает только при соблюдении стандартов: объявление DOCTYPE страницы обязательно.

js
(function () {  if (!Event.prototype.preventDefault) {    Event.prototype.preventDefault = function () {      this.returnValue = false;    };  }  if (!Event.prototype.stopPropagation) {    Event.prototype.stopPropagation = function () {      this.cancelBubble = true;    };  }  if (!Element.prototype.addEventListener) {    var eventListeners = [];    var addEventListener = function (      type,      listener /*, useCapture (will be ignored) */,    ) {      var self = this;      var wrapper = function (e) {        e.target = e.srcElement;        e.currentTarget = self;        if (listener.handleEvent) {          listener.handleEvent(e);        } else {          listener.call(self, e);        }      };      if (type == "DOMContentLoaded") {        var wrapper2 = function (e) {          if (document.readyState == "complete") {            wrapper(e);          }        };        document.attachEvent("onreadystatechange", wrapper2);        eventListeners.push({          object: this,          type: type,          listener: listener,          wrapper: wrapper2,        });        if (document.readyState == "complete") {          var e = new Event();          e.srcElement = window;          wrapper2(e);        }      } else {        this.attachEvent("on" + type, wrapper);        eventListeners.push({          object: this,          type: type,          listener: listener,          wrapper: wrapper,        });      }    };    var removeEventListener = function (      type,      listener /*, useCapture (will be ignored) */,    ) {      var counter = 0;      while (counter < eventListeners.length) {        var eventListener = eventListeners[counter];        if (          eventListener.object == this &&          eventListener.type == type &&          eventListener.listener == listener        ) {          if (type == "DOMContentLoaded") {            this.detachEvent("onreadystatechange", eventListener.wrapper);          } else {            this.detachEvent("on" + type, eventListener.wrapper);          }          eventListeners.splice(counter, 1);          break;        }        ++counter;      }    };    Element.prototype.addEventListener = addEventListener;    Element.prototype.removeEventListener = removeEventListener;    if (HTMLDocument) {      HTMLDocument.prototype.addEventListener = addEventListener;      HTMLDocument.prototype.removeEventListener = removeEventListener;    }    if (Window) {      Window.prototype.addEventListener = addEventListener;      Window.prototype.removeEventListener = removeEventListener;    }  }})();

Старый способ регистрации обработчиков событий

addEventListener() был добавлен в спецификации DOM 2Events. До этого обработчики добавлялись следующим образом:

js
// Передача ссылки на функцию — не добавляйте '()' после него, это вызовет функцию!el.onclick = modifyText;// Использование функционального выраженияelement.onclick = function () {  // ... логика функции ...};

Этот метод заменяет текущие обработчики событияclick, если они есть. Тоже самое для других событий и ассоциируемых с ними обработчиков, таких какblur (onblur),keypress (onkeypress), и так далее.

Так как это по существу было частью DOM 0, этот метод имеет широкую поддержку и не требует специального кросс-браузерного кода; следовательно, это обычно используется, чтобы добавлять обработчики динамически, если не требуются расширенные возможностиaddEventListener().

Вопросы памяти

js
var i;var els = document.getElementsByTagName("*");// Случай 1for (i = 0; i < els.length; i++) {  els[i].addEventListener(    "click",    function (e) {      /*некоторые действия*/    },    false,  );}// Случай 2function processEvent(e) {  /*некоторые действия*/}for (i = 0; i < els.length; i++) {  els[i].addEventListener("click", processEvent, false);}

В первом случае новая (анонимная) функция создаётся при каждом шаге цикла. Во втором случае одна заранее объявленная функция используется как обработчик события. Из этого следует меньшее потребление памяти. Более того, в первом случае, вследствие отсутствия ссылок на анонимные функции, невозможно вызватьelement.removeEventListener, потому что нет ссылки на обработчик, в то время, как во втором случае возможно вызватьmyElement.removeEventListener("click", processEvent, false).

Улучшение производительности прокрутки с помощью пассивных слушателей

Значение по умолчанию для параметраpassive -false. Начиная с Chrome 56 (desktop, Chrome for Android, Android webview) значение по умолчанию дляtouchstart иtouchmove равноtrue, а вызовыpreventDefault() не разрешены. Чтобы отменить это поведение, необходимо установить параметрpassive вfalse (см. пример ниже). Это изменение не позволяет обработчику блокировать показ страницы во время прокрутки пользователя. Демонстрация доступна насайте разработчиков Google. Обратите внимание, что Edge вообще не поддерживаетoptions, и добавление его безпроверки поддержки помешает использовать аргументuseCapture.

js
/* Не позволяем обработчику блокировать показ страницы */var passiveSupported = false;try {  window.addEventListener(    "test",    null,    Object.defineProperty({}, "passive", {      get: function () {        passiveSupported = true;      },    }),  );} catch (err) {}/* Добавляем обработчик событий */var elem = document.getElementById("elem");elem.addEventListener(  "touchmove",  function listener() {    /* do something */  },  passiveSupported ? { passive: true } : false,);

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

Спецификации

Specification
DOM
# ref-for-dom-eventtarget-addeventlistener③

Совместимость с браузерами

Дополнительная информация

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp