Tylko pytanie: czy istnieje sposób, aby całkowicie usunąć wszystkie zdarzenia obiektu, np. Div?
EDYCJA: dodaję na div.addEventListener('click',eventReturner(),false);
wydarzenie.
function eventReturner() {
return function() {
dosomething();
};
}
EDIT2: znalazłem sposób, który działa, ale nie można go użyć w moim przypadku:
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
Florian Müller
źródło
źródło
div.onclick=null
. Oczywiście nie powinieneś używaćaddEventListener
w tym przypadku całkowicie, ponieważ doda to oddzielny słuchacz inny niż wonclick
.Odpowiedzi:
Nie jestem pewien, co masz na myśli, mówiąc o usunięciu wszystkich wydarzeń . Usunąć wszystkie programy obsługi dla określonego typu zdarzenia lub wszystkie programy obsługi zdarzeń dla jednego typu?
Usuń wszystkie programy obsługi zdarzeń
Jeśli chcesz usunąć wszystkie programy obsługi zdarzeń (dowolnego typu), możesz sklonować element i zastąpić go jego klonem:
var clone = element.cloneNode(true);
Uwaga: zachowa to atrybuty i elementy podrzędne, ale nie zachowa żadnych zmian we właściwościach DOM.
Usuń „anonimowe” programy obsługi zdarzeń określonego typu
Innym sposobem jest użycie,
removeEventListener()
ale myślę, że już próbowałeś tego i nie zadziałało. Oto haczyk :Zasadniczo przekazujesz anonimową funkcję do
addEventListener
aseventReturner
zwraca funkcję.Masz dwie możliwości rozwiązania tego problemu:
Nie używaj funkcji, która zwraca funkcję. Użyj funkcji bezpośrednio:
function handler() { dosomething(); } div.addEventListener('click',handler,false);
Utwórz opakowanie
addEventListener
przechowujące odniesienie do zwróconej funkcji i utwórz dziwnąremoveAllEvents
funkcję: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, ) }
A potem możesz go użyć z:
addListener(div, 'click', eventReturner(), false) // and later removeAllListeners(div, 'click')
PRÓBNY
Uwaga: Jeśli twój kod działa przez długi czas i tworzysz i usuwasz wiele elementów, musiałbyś upewnić się, że usuniesz elementy zawarte w,
_eventHandlers
gdy je zniszczysz.źródło
element.parentNode
może to być null. Powinien prawdopodobnie umieścić if check wokół tego fragmentu kodu powyżej.Spowoduje to usunięcie wszystkich słuchaczy z dzieci, ale będzie powolne w przypadku dużych stron. Brutalnie proste do napisania.
źródło
document.querySelector('body').outerHTML = document.querySelector('body').outerHTML
pracował dla mnie.document.querySelector('body').outerHTML
ciebie możesz po prostu wpisaćdocument.body.outerHTML
Użyj własnej funkcji detektora zdarzeń
remove()
. Na przykład:getEventListeners().click.forEach((e)=>{e.remove()})
źródło
getEventListeners
to, że jest dostępny tylko w narzędziach deweloperskich WebKit i FireBug. Nie jest to coś, co możesz po prostu wpisać w swoim kodzie.getEventListeners()
. przykład:getEventListeners(document)
lubgetEventListeners(document.querySelector('.someclass'))
getEventListeners(document).click.forEach((e)=>{e.remove()})
generuje ten błąd:VM214:1 Uncaught TypeError: e.remove is not a function
Jak mówi corwin.amber, istnieją różnice między Webkitem a innymi.
W przeglądarce Chrome:
getEventListeners(document);
Co daje Ci obiekt ze wszystkimi istniejącymi odbiornikami zdarzeń:
Object click: Array[1] closePopups: Array[1] keyup: Array[1] mouseout: Array[1] mouseover: Array[1] ...
Z tego miejsca możesz dotrzeć do słuchacza, którego chcesz usunąć:
getEventListeners(document).copy[0].remove();
Więc wszyscy słuchacze wydarzenia:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { o.remove(); } ) }
W przeglądarce Firefox
Jest trochę inny, ponieważ używa opakowania nasłuchującego, które nie zawiera funkcji usuwania. Musisz zdobyć odbiorcę, którego chcesz usunąć:
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
Wszyscy słuchacze wydarzeń:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { document.removeEventListener(eventType, o.listener) } ) }
Natknąłem się na ten post, próbując wyłączyć irytującą ochronę przed kopiowaniem witryny z wiadomościami.
Cieszyć się!
źródło
getEventListeners
nie jest zdefiniowane?Możesz dodać funkcję widełek do przechwytywania wszystkich połączeń
addEventHandler
. Hak spowoduje wypchnięcie programu obsługi do listy, której można użyć do czyszczenia. Na przykład,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; }
Powinieneś wstawić ten kod u góry głównej strony internetowej (np
index.html
.). Podczas czyszczenia możesz zapętlić all_handlers i wywołać metodę removeEventHandler dla każdego z nich. Nie martw się o wielokrotne wywoływanie metody removeEventHandler z tą samą funkcją. To jest nieszkodliwe.Na przykład,
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); } }
Uwaga: w przypadku IE użyj Element zamiast EventTarget i zmień => na funkcję i różne inne rzeczy.
źródło
Aby uzupełnić odpowiedzi, oto rzeczywiste przykłady usuwania zdarzeń, gdy odwiedzasz strony internetowe i nie masz kontroli nad generowanym kodem HTML i JavaScript.
Niektóre irytujące witryny uniemożliwiają kopiowanie i wklejanie nazw użytkowników w formularzach logowania, co można by łatwo ominąć, gdyby
onpaste
zdarzenie zostało dodane zonpaste="return false"
atrybutem HTML. W tym przypadku wystarczy kliknąć prawym przyciskiem myszy pole wejściowe, wybrać opcję „Sprawdź element” w przeglądarce takiej jak Firefox i usunąć atrybut HTML.Jeśli jednak zdarzenie zostało dodane za pomocą JavaScript w następujący sposób:
document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};
Będziemy musieli również usunąć zdarzenie za pomocą JavaScript:
document.getElementById("lyca_login_mobile_no").onpaste = null;
W moim przykładzie użyłem identyfikatora „lyca_login_mobile_no”, ponieważ był to identyfikator wprowadzania tekstu używany przez odwiedzaną witrynę internetową.
Innym sposobem na usunięcie zdarzenia (który również usunie wszystkie zdarzenia) jest usunięcie węzła i utworzenie nowego, tak jak musimy to zrobić, jeśli
addEventListener
został użyty do dodania zdarzeń przy użyciu funkcji anonimowej, której nie możemy usunąćremoveEventListener
. Można to również zrobić za pomocą konsoli przeglądarki, sprawdzając element, kopiując kod HTML, usuwając kod HTML, a następnie wklejając kod HTML w tym samym miejscu.Można to również zrobić szybciej i zautomatyzować za pomocą JavaScript:
var oldNode = document.getElementById("lyca_login_mobile_no"); var newNode = oldNode.cloneNode(true); oldNode.parentNode.insertBefore(newNode, oldNode); oldNode.parentNode.removeChild(oldNode);
Aktualizacja: jeśli aplikacja internetowa została utworzona przy użyciu struktury JavaScript, takiej jak Angular, wygląda na to, że poprzednie rozwiązania nie działają lub nie psują aplikacji. Innym obejściem umożliwiającym wklejanie byłoby ustawienie wartości za pomocą JavaScript:
document.getElementById("lyca_login_mobile_no").value = "username";
W tej chwili nie wiem, czy istnieje sposób na usunięcie wszystkich zdarzeń walidacji formularzy i ograniczeń bez niszczenia aplikacji napisanej w całości w JavaScript, takiej jak Angular.
źródło
możesz dodać funkcję i usunąć wszystkie inne kliknięcia, przypisując je
btn1 = document.querySelector(".btn-1") btn1.addEventListener("click" , _=>{console.log("hello")}) btn1.addEventListener("click" , _=>{console.log("How Are you ?")}) btn2 = document.querySelector(".btn-2") btn2.onclick = _=>{console.log("Hello")} btn2.onclick = _=>{console.log("Bye")}
<button class="btn-1">Hello to Me</button> <button class="btn-2">Hello to Bye</button>
źródło
angular ma wypełnienie dla tego problemu, możesz sprawdzić. Nie rozumiałem wiele, ale może to pomoże.
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; } };
....
źródło
EVENT_NAME_SYMBOL_REGX
ma pochodzić?Możesz dodać funkcję pomocniczą, która na przykład czyści nasłuchiwanie zdarzeń
function clearEventListener(element) { const clonedElement = element.cloneNode(true); element.replaceWith(clonedElement); return clonedElement; }
wystarczy przekazać element do funkcji i to wszystko ...
źródło
var div = getElementsByTagName('div')[0]; /* first div found; you can use getElementById for more specific element */ div.onclick = null; // OR: div.onclick = function(){};
//edytować
Nie wiedziałem, jakiej metody używasz do dołączania wydarzeń. Dla
addEventListener
można użyć to:div.removeEventListener('click',functionName,false); // functionName is the name of your callback function
więcej szczegółów
źródło
div.onClick = something
to ustawia inne zdarzenie onClick, ale poprzednie pozostaje, więc mam na poprzednie i jedno na przykład null ...addEventListener()
.addEventListener()
...Być może przeglądarka zrobi to za Ciebie, jeśli zrobisz coś takiego:
Skopiować
div
i jego atrybuty i wstawić przed starą, a następnie przenieść zawartość ze starej do nowej i usunąć starą?źródło
Usuwanie wszystkich wydarzeń z
document
:Jedna wkładka:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
Ładna wersja:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
źródło
Tylko Chrome
Ponieważ próbuję usunąć EventListener w teście Protractor i nie mam dostępu do Listenera w teście, poniższe działa, aby usunąć wszystkie detektory zdarzeń jednego typu:
function(eventType){ getEventListeners(window).[eventType].forEach( function(e){ window.removeEventListener(eventType, e.listener) } ); }
Mam nadzieję, że komuś to pomogło, ponieważ poprzednia odpowiedź używała metody „usuń”, która od tego czasu już nie działa.
źródło
Jedną z metod jest dodanie nowego detektora zdarzeń, który wywołuje funkcję e.stopImmediatePropagation ().
źródło