Apenas questione: existe alguma maneira de remover completamente todos os eventos de um objeto, por exemplo, um div?
EDIT: Estou adicionando por div.addEventListener('click',eventReturner(),false);
evento.
function eventReturner() {
return function() {
dosomething();
};
}
EDIT2: Encontrei uma maneira que está funcionando, mas não é possível usar no meu caso:
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
fonte
fonte
div.onclick=null
. É claro que você não deve usaraddEventListener
neste caso totalmente, pois isso adicionará um ouvinte separado diferente daquele emonclick
.Respostas:
Não tenho certeza do que você quer dizer com remover todos os eventos . Remover todos os manipuladores de um tipo específico de evento ou todos os manipuladores de um tipo?
Remova todos os manipuladores de eventos
Se você deseja remover todos os manipuladores de eventos (de qualquer tipo), pode clonar o elemento e substituí-lo por seu clone:
var clone = element.cloneNode(true);
Observação: isso preservará atributos e filhos, mas não preservará nenhuma alteração nas propriedades do DOM.
Remova manipuladores de eventos "anônimos" de tipo específico
A outra maneira é usar,
removeEventListener()
mas acho que você já tentou isso e não funcionou. Aqui está o problema :Você está essencialmente passando uma função anônima para
addEventListener
aseventReturner
retorna uma função.Você tem duas possibilidades para resolver isso:
Não use uma função que retorna uma função. Use a função diretamente:
function handler() { dosomething(); } div.addEventListener('click',handler,false);
Crie um wrapper para
addEventListener
que armazene uma referência à função retornada e crie algumaremoveAllEvents
função estranha :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, ) }
E então você pode usá-lo com:
addListener(div, 'click', eventReturner(), false) // and later removeAllListeners(div, 'click')
DEMO
Nota: Se o seu código for executado por um longo tempo e você estiver criando e removendo muitos elementos, você deve certificar-se de remover os elementos contidos em
_eventHandlers
ao destruí-los.fonte
element.parentNode
pode ser nulo. Provavelmente deveria colocar uma verificação if em torno do trecho de código acima.Isso removerá todos os ouvintes das crianças, mas será lento para páginas grandes. Brutalmente simples de escrever.
fonte
document.querySelector('body').outerHTML = document.querySelector('body').outerHTML
trabalhou para mim.document.querySelector('body').outerHTML
você pode simplesmente digitardocument.body.outerHTML
Use a própria função do ouvinte de evento
remove()
. Por exemplo:getEventListeners().click.forEach((e)=>{e.remove()})
fonte
getEventListeners
só está disponível nas ferramentas de desenvolvimento WebKit e no FireBug. Não é algo que você pode simplesmente chamar em seu código.getEventListeners()
. exemplo:getEventListeners(document)
ougetEventListeners(document.querySelector('.someclass'))
getEventListeners(document).click.forEach((e)=>{e.remove()})
produz este erro:VM214:1 Uncaught TypeError: e.remove is not a function
Como diz corwin.amber, existem diferenças entre o Webkit e os outros.
No Chrome:
getEventListeners(document);
O que dá a você um objeto com todos os ouvintes de evento existentes:
Object click: Array[1] closePopups: Array[1] keyup: Array[1] mouseout: Array[1] mouseover: Array[1] ...
A partir daqui, você pode alcançar o ouvinte que deseja remover:
getEventListeners(document).copy[0].remove();
Portanto, todos os ouvintes de eventos:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { o.remove(); } ) }
No Firefox
É um pouco diferente porque usa um wrapper de ouvinte que não contém a função de remoção. Você deve obter o listener que deseja remover:
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
Todos os ouvintes do evento:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { document.removeEventListener(eventType, o.listener) } ) }
Tropecei com esta postagem tentando desativar a irritante proteção contra cópia de um site de notícias.
Apreciar!
fonte
getEventListeners
não está definido?Você pode adicionar uma função de gancho para interceptar todas as chamadas
addEventHandler
. O gancho empurrará o manipulador para uma lista que pode ser usada para limpeza. Por exemplo,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; }
Você deve inserir este código próximo ao topo de sua página principal da web (por exemplo
index.html
). Durante a limpeza, você pode fazer um loop por all_handlers e chamar removeEventHandler para cada um. Não se preocupe em chamar removeEventHandler várias vezes com a mesma função. É inofensivo.Por exemplo,
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); } }
Nota: para o IE, use Element em vez de EventTarget e mude => para funcionar, e várias outras coisas.
fonte
Para completar as respostas, aqui estão exemplos do mundo real de remoção de eventos quando você visita sites e não tem controle sobre o código HTML e JavaScript gerado.
Alguns sites irritantes estão impedindo que você copie e cole nomes de usuário em formulários de login, o que poderia ser facilmente contornado se o
onpaste
evento fosse adicionado com oonpaste="return false"
atributo HTML. Nesse caso, basta clicar com o botão direito do mouse no campo de entrada, selecionar "Inspecionar elemento" em um navegador como o Firefox e remover o atributo HTML.No entanto, se o evento foi adicionado por meio de JavaScript assim:
document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};
Teremos que remover o evento por JavaScript também:
document.getElementById("lyca_login_mobile_no").onpaste = null;
No meu exemplo, usei o ID "lyca_login_mobile_no", pois era o ID de entrada de texto usado pelo site que estava visitando.
Outra forma de remover o evento (que também removerá todos os eventos) é remover o nó e criar um novo, como temos que fazer se
addEventListener
foi usado para adicionar eventos usando uma função anônima que não podemos remover comremoveEventListener
. Isso também pode ser feito por meio do console do navegador, inspecionando um elemento, copiando o código HTML, removendo o código HTML e, em seguida, colando o código HTML no mesmo lugar.Também pode ser feito de forma mais rápida e automatizada por meio de JavaScript:
var oldNode = document.getElementById("lyca_login_mobile_no"); var newNode = oldNode.cloneNode(true); oldNode.parentNode.insertBefore(newNode, oldNode); oldNode.parentNode.removeChild(oldNode);
Atualização: se o aplicativo da web é feito usando uma estrutura JavaScript como Angular, parece que as soluções anteriores não estão funcionando ou quebrando o aplicativo. Outra solução alternativa para permitir a colagem seria definir o valor por meio de JavaScript:
document.getElementById("lyca_login_mobile_no").value = "username";
No momento, não sei se existe uma maneira de remover todos os eventos de validação e restrição de formulário sem quebrar um aplicativo escrito inteiramente em JavaScript como o Angular.
fonte
você pode adicionar função e remover todos os outros cliques atribuindo-os
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>
fonte
angular tem um polyfill para esse problema, você pode verificar. Não entendi muito, mas talvez possa ajudar.
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; } };
....
fonte
EVENT_NAME_SYMBOL_REGX
deveria vir?Você pode adicionar uma função auxiliar que limpa o ouvinte de eventos, por exemplo
function clearEventListener(element) { const clonedElement = element.cloneNode(true); element.replaceWith(clonedElement); return clonedElement; }
basta passar o elemento para a função e pronto ...
fonte
var div = getElementsByTagName('div')[0]; /* first div found; you can use getElementById for more specific element */ div.onclick = null; // OR: div.onclick = function(){};
//editar
Eu não sabia qual método você está usando para anexar eventos. Pois
addEventListener
você pode usar isto:div.removeEventListener('click',functionName,false); // functionName is the name of your callback function
mais detalhes
fonte
div.onClick = something
, ele define outro evento onClick, mas o anterior permanece, então eu tenho no anterior e um por exemplo nulo ...addEventListener()
.addEventListener()
...Pode ser que o navegador faça isso por você se você fizer algo como:
Copie o
div
e seus atributos e insira-o antes do antigo, mova o conteúdo do antigo para o novo e exclua o antigo?fonte
Removendo todos os eventos em
document
:Um liner:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
Versão bonita:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
fonte
Apenas Chrome
Como estou tentando remover um EventListener dentro de um teste de Protractor e não tenho acesso ao Listener no teste, o seguinte funciona para remover todos os ouvintes de evento de um único tipo:
function(eventType){ getEventListeners(window).[eventType].forEach( function(e){ window.removeEventListener(eventType, e.listener) } ); }
Espero que isso ajude alguém, pois a resposta anterior estava usando o método "remover" que desde então não funciona mais.
fonte
Um método é adicionar um novo ouvinte de evento que chama e.stopImmediatePropagation ().
fonte