Просто вопрос: есть ли способ полностью удалить все события объекта, например, div?
РЕДАКТИРОВАТЬ: я добавляю для каждого div.addEventListener('click',eventReturner(),false);
события.
function eventReturner() {
return function() {
dosomething();
};
}
EDIT2: я нашел способ, который работает, но не подходит для моего случая:
var returnedFunction;
function addit() {
var div = document.getElementById('div');
returnedFunction = eventReturner();
div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
var div = document.getElementById('div');
div.removeEventListener('click',returnedFunction,false);
}
javascript
events
dom
Флориан Мюллер
источник
источник
div.onclick=null
. Конечно, вы не должны использоватьaddEventListener
в этом случае вообще, так как это добавит отдельного слушателя, отличного от того, что находится вonclick
.Ответы:
Я не уверен, что вы имеете в виду под удалением всех событий . Удалить все обработчики событий определенного типа или все обработчики событий одного типа?
Удалить все обработчики событий
Если вы хотите удалить все обработчики событий (любого типа), вы можете клонировать элемент и заменить его его клоном:
var clone = element.cloneNode(true);
Примечание. Это сохранит атрибуты и дочерние элементы, но не сохранит никаких изменений свойств DOM.
Удалить "анонимные" обработчики событий определенного типа.
Другой способ - использовать,
removeEventListener()
но я думаю, вы уже пробовали это, и это не сработало. Вот и загвоздка :По сути, вы передаете анонимную функцию в
addEventListener
as,eventReturner
возвращающую функцию.У вас есть две возможности решить эту проблему:
Не используйте функцию, возвращающую функцию. Используйте функцию напрямую:
function handler() { dosomething(); } div.addEventListener('click',handler,false);
Создайте оболочку для
addEventListener
хранения ссылки на возвращаемую функцию и создайте какую-нибудь страннуюremoveAllEvents
функцию:var _eventHandlers = {}; // somewhere global const addListener = (node, event, handler, capture = false) => { if (!(event in _eventHandlers)) { _eventHandlers[event] = [] } // here we track the events and their nodes (note that we cannot // use node as Object keys, as they'd get coerced into a string _eventHandlers[event].push({ node: node, handler: handler, capture: capture }) node.addEventListener(event, handler, capture) } const removeAllListeners = (targetNode, event) => { // remove listeners from the matching nodes _eventHandlers[event] .filter(({ node }) => node === targetNode) .forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture)) // update _eventHandlers global _eventHandlers[event] = _eventHandlers[event].filter( ({ node }) => node !== targetNode, ) }
И тогда вы можете использовать его с:
addListener(div, 'click', eventReturner(), false) // and later removeAllListeners(div, 'click')
ДЕМО
Примечание. Если ваш код работает в течение длительного времени, и вы создаете и удаляете множество элементов, вам нужно обязательно удалить элементы, содержащиеся в,
_eventHandlers
когда вы их уничтожаете.источник
element.parentNode
может быть null. Вероятно, следует поставить проверку if вокруг этого фрагмента кода выше.Это удалит всех слушателей из детей, но будет медленным для больших страниц. Писать очень просто.
источник
document.querySelector('body').outerHTML = document.querySelector('body').outerHTML
работал у меня.document.querySelector('body').outerHTML
вас можете просто ввестиdocument.body.outerHTML
Используйте собственную функцию прослушивателя событий
remove()
. Например:getEventListeners().click.forEach((e)=>{e.remove()})
источник
getEventListeners
это доступно только в инструментах разработчика WebKit и в FireBug. Это не то, что вы можете просто вызвать в своем коде.getEventListeners()
. Например:getEventListeners(document)
илиgetEventListeners(document.querySelector('.someclass'))
getEventListeners(document).click.forEach((e)=>{e.remove()})
выдает эту ошибку:VM214:1 Uncaught TypeError: e.remove is not a function
Как говорит corwin.amber, между Webkit и другими есть различия.
В Chrome:
getEventListeners(document);
Это дает вам объект со всеми существующими прослушивателями событий:
Object click: Array[1] closePopups: Array[1] keyup: Array[1] mouseout: Array[1] mouseover: Array[1] ...
Отсюда вы можете добраться до слушателя, которого хотите удалить:
getEventListeners(document).copy[0].remove();
Итак, все слушатели событий:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { o.remove(); } ) }
В Firefox
Немного отличается, потому что он использует оболочку слушателя, которая не содержит функции удаления. Вы должны получить слушателя, который хотите удалить:
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
Все слушатели событий:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { document.removeEventListener(eventType, o.listener) } ) }
Я наткнулся на этот пост, пытаясь отключить надоедливую защиту от копирования на новостном веб-сайте.
Наслаждайтесь!
источник
getEventListeners
это не определено?Вы можете добавить функцию перехвата для перехвата всех вызовов
addEventHandler
. Хук подтолкнет обработчик к списку, который можно использовать для очистки. Например,if (EventTarget.prototype.original_addEventListener == null) { EventTarget.prototype.original_addEventListener = EventTarget.prototype.addEventListener; function addEventListener_hook(typ, fn, opt) { console.log('--- add event listener',this.nodeName,typ); this.all_handlers = this.all_handlers || []; this.all_handlers.push({typ,fn,opt}); this.original_addEventListener(typ, fn, opt); } EventTarget.prototype.addEventListener = addEventListener_hook; }
Вы должны вставить этот код в верхнюю часть вашей главной веб-страницы (например
index.html
). Во время очистки вы можете пройти через all_handlers и вызвать removeEventHandler для каждого. Не беспокойтесь о многократном вызове removeEventHandler с одной и той же функцией. Это безвредно.Например,
function cleanup(elem) { for (let t in elem) if (t.startsWith('on') && elem[t] != null) { elem[t] = null; console.log('cleanup removed listener from '+elem.nodeName,t); } for (let t of elem.all_handlers || []) { elem.removeEventListener(t.typ, t.fn, t.opt); console.log('cleanup removed listener from '+elem.nodeName,t.typ); } }
Примечание: для IE используйте Element вместо EventTarget, и измените => на функцию и многое другое.
источник
Чтобы завершить ответы, вот реальные примеры удаления событий, когда вы посещаете веб-сайты и не можете контролировать сгенерированный код HTML и JavaScript.
Некоторые надоедливые веб-сайты мешают вам копировать и вставлять имена пользователей в формы входа, что можно было бы легко обойти, если бы
onpaste
событие было добавлено сonpaste="return false"
атрибутом HTML. В этом случае нам просто нужно щелкнуть правой кнопкой мыши в поле ввода, выбрать «Проверить элемент» в браузере, таком как Firefox, и удалить атрибут HTML.Однако, если событие было добавлено через JavaScript следующим образом:
document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};
Нам также придется удалить событие через JavaScript:
document.getElementById("lyca_login_mobile_no").onpaste = null;
В моем примере я использовал идентификатор lyca_login_mobile_no, поскольку это был идентификатор ввода текста, используемый веб-сайтом, который я посещал.
Другой способ удалить событие (которое также удалит все события) - удалить узел и создать новый, как мы должны сделать, если
addEventListener
использовались для добавления событий с использованием анонимной функции, которую мы не можем удалить с помощьюremoveEventListener
. Это также можно сделать через консоль браузера, проверив элемент, скопировав HTML-код, удалив HTML-код и затем вставив HTML-код в то же место.Это также можно сделать быстрее и автоматизировать с помощью JavaScript:
var oldNode = document.getElementById("lyca_login_mobile_no"); var newNode = oldNode.cloneNode(true); oldNode.parentNode.insertBefore(newNode, oldNode); oldNode.parentNode.removeChild(oldNode);
Обновление: если веб-приложение создано с использованием инфраструктуры JavaScript, такой как Angular, похоже, что предыдущие решения не работают или нарушают работу приложения. Другой обходной путь для разрешения вставки - установка значения через JavaScript:
document.getElementById("lyca_login_mobile_no").value = "username";
На данный момент я не знаю, есть ли способ удалить все события проверки и ограничения формы без нарушения работы приложения, полностью написанного на JavaScript, например Angular.
источник
У angular есть полифилл для этой проблемы, вы можете проверить. Я мало что понял, но, возможно, это поможет.
const REMOVE_ALL_LISTENERS_EVENT_LISTENER = 'removeAllListeners';
proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () { const target = this || _global; const eventName = arguments[0]; if (!eventName) { const keys = Object.keys(target); for (let i = 0; i < keys.length; i++) { const prop = keys[i]; const match = EVENT_NAME_SYMBOL_REGX.exec(prop); let evtName = match && match[1]; // in nodejs EventEmitter, removeListener event is // used for monitoring the removeListener call, // so just keep removeListener eventListener until // all other eventListeners are removed if (evtName && evtName !== 'removeListener') { this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName); } } // remove removeListener listener finally this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener'); } else { const symbolEventNames = zoneSymbolEventNames$1[eventName]; if (symbolEventNames) { const symbolEventName = symbolEventNames[FALSE_STR]; const symbolCaptureEventName = symbolEventNames[TRUE_STR]; const tasks = target[symbolEventName]; const captureTasks = target[symbolCaptureEventName]; if (tasks) { const removeTasks = tasks.slice(); for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } if (captureTasks) { const removeTasks = captureTasks.slice(); for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } } } if (returnTarget) { return this; } };
....
источник
EVENT_NAME_SYMBOL_REGX
взяться?Вы можете добавить вспомогательную функцию, которая, например, очищает прослушиватель событий.
function clearEventListener(element) { const clonedElement = element.cloneNode(true); element.replaceWith(clonedElement); return clonedElement; }
просто передайте элемент в функцию и все ...
источник
var div = getElementsByTagName('div')[0]; /* first div found; you can use getElementById for more specific element */ div.onclick = null; // OR: div.onclick = function(){};
//редактировать
Я не знал, какой метод вы используете для прикрепления событий. Для
addEventListener
вы можете использовать это:div.removeEventListener('click',functionName,false); // functionName is the name of your callback function
подробнее подробнее
источник
div.onClick = something
тогда он установит другое событие onClick, но предыдущее останется, поэтому у меня есть предыдущее и одно, например, null ...addEventListener()
.addEventListener()
...Может быть, браузер сделает это за вас, если вы сделаете что-то вроде:
Скопируйте
div
и его атрибуты и вставьте перед старым, затем переместите содержимое из старого в новое и удалите старое?источник
Удаление всех событий на
document
:Один лайнер:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
Симпатичная версия:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
источник
Только Chrome
Поскольку я пытаюсь удалить EventListener в тесте Protractor и не имею доступа к Listener в тесте, для удаления всех прослушивателей событий одного типа работает следующее:
function(eventType){ getEventListeners(window).[eventType].forEach( function(e){ window.removeEventListener(eventType, e.listener) } ); }
Я надеюсь, что это поможет кому-то, поскольку в предыдущем ответе использовался метод «удалить», который с тех пор больше не работает.
источник
Один из способов - добавить новый прослушиватель событий, который вызывает e.stopImmediatePropagation ().
источник