CoderNotes - заметки программиста

Публикации  »  JavaScript + jQuery
Скидка 65% на Skillbox

Получите скидку 65% на любой курс программирования на популярной образовательной платформе Skillbox!

Подробнее
Бесплатный хостинг + SSL-сертификат

Зарегистрируйте домен и получите 2 месяца бесплатного хостинга и SSL-сертификат на 1 год в подарок

Подробнее

Удаление всех Event Listeners (слушателей событий) у элемента

На момент написания статьи в JavaScript есть метод removeEventListener, который удаляет конкретный слушатель события на элементе. Однако, с его помощью не получится удалить слушатель - если не известно какая функция используется в качестве слушателя или если используется анонимная функция как слушатель.

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

1. Замена элемента на его клон

Если создать элемент на странице заново, то он будет без каких-либо событий. Сделать это можно с помощью cloneNode.

Однако, клонированный элемент так же получит и все его атрибуты, в т.ч. атрибуты событий (on-event атрибуты), такие, как onclick, onchange, onblur и т.д. Поэтому, от них необходимо избавиться перед клонированием элемента, если есть вероятность, что эти атрибуты могли быть установлены ранее.

const el = document.getElementById('element');
el.removeAttribute('onclick'); 
el.replaceWith(el.cloneNode(true));

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

Есть так же аналог клонирования, выполняемый немного другим методом:

const el = document.getElementById('element');
el.outerHTML = el.outerHTML;

Фактически, это то же самое клонирование и имеет те же недостатки, что и cloneNode.

2. Создать обёртку для addEventListener

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

var _eventHandlers = {};

const addListener = (node, event, handler, capture = false) => {
  if (!(event in _eventHandlers)) {
    _eventHandlers[event] = [];
  }
  _eventHandlers[event].push({ node: node, handler: handler, capture: capture });
  node.addEventListener(event, handler, capture);
}

const removeAllListeners = (targetNode, event) => {
  _eventHandlers[event]
    .filter(({ node }) => node === targetNode)
    .forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture));
  _eventHandlers[event] = _eventHandlers[event].filter(
    ({ node }) => node !== targetNode,
  );
}

// Теперь можно добавлять и удалять события так:

const el = document.getElementById('element'); 
addListener(el, 'click', eventFunction, false);

removeAllListeners(el, 'click');

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

el = document.getElementById('element');
addListener(el, 'click', function() { alert('1') }, false);
addListener(el, 'click', () => alert("2"), false);
addListener(el, 'click', { handleEvent(event) { alert('3'); } }, false);

// Удаляем все выше назначенные обработчики
removeAllListeners(document.getElementById('element'), 'click');

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

el = document.getElementById('element');
for (event in _eventHandlers) {
  removeAllListeners(el, event);
}

3. Использовать jQuery

Если вы используете для работы с событиями jQuery, то события можно удалять с помощью функции .off(), которая принимает 3 необязательных параметра: название события (строка), селектор (строка) и обработчик (функция) (почитать подробнее api.jquery.com).

Пример назначения и удаления обработчиков событий с помощью jQuery:

$('#element').click(function(){ console.log('1'); });
$('#element').on('contextmenu', function(){ console.log('2'); });
$('#element').bind('mouseover', () => { console.log('3'); });

// удаляем все обработчики события "click" с элемента
$('#element').off('click');
// удаляем все обработчики с элемента
$('#element').off();

Обратите внимание: Если используется назначение обработчиков событий "вперемешку", т.е. какие-то обработчики были назначены на чистом JavaScript, а какие-то через jQuery, то тогда .off() удалит только обработчики назначенные jQuery, а остальные останутся без изменений.

 

Информация для статьи взята по большей части из https://stackoverflow.com, после чего в материал добавлены мои комментарии и примеры.

 

Категория: JavaScript + jQuery

Книги по теме:

Посмотреть все книги по программированию

Комментарии к статье:

31.08.24   Гость Круто

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