2010-05-14 12 views
32

Vorrei rimuovere TUTTI i gestori per un determinato tipo di evento. Diciamo che ho aggiunto due volte "evento onclick" a un pulsante e ora vorrei tornare allo stato originale in cui nessun gestore di eventi era impostato sul pulsante.È possibile rimuovere tutti i gestori di eventi di un determinato elemento in javascript?

Come posso farlo?

PS: Ho trovato i metodi removeEventListener (non-IE)/detachEvent (IE) ma le funzioni mi vogliono passare come parametro la funzione che gestisce l'evento che mi sembra abbastanza maldestro perché dovrei memorizzare le funzioni da qualche parte.

EDIT: http://ejohn.org/blog/flexible-javascript-events/ - Ora sto utilizzando questo codice

+1

Stai utilizzando l'attributo onclick in linea? – Mottie

+0

+1 Ottima domanda. –

+0

Un'opzione migliore e più diretta è usare la soluzione di @ jiggy http://stackoverflow.com/questions/803936/how-to-clear-remove-javascript-event-handler – chowey

risposta

7

http://www.quirksmode.org/js/events_advanced.html - "Quali gestori di eventi sono registrati?" - a quanto pare non è possibile senza DOM 3 livello :-(

EDIT: mi è venuta in mente questo codice Si adatta alle mie esigenze Forse sarà utile per qualcun altro

Javascript:

... pagina
function DomLib() { 


} 


/** 
* Based on: http://ejohn.org/blog/flexible-javascript-events/ 
* Function that register event and enables it to be removed without explicitly giving the function definition 
*/ 
DomLib.prototype.regEventEx = function (el, eventName, funct) { 

    if (el.attachEvent) { 
    el['e'+eventName+funct] = funct; 
    el[eventName+funct] = function(){el['e'+eventName+funct](window.event);} 
    el.attachEvent('on'+eventName, el[eventName+funct]); 
    } else {  
    el.addEventListener(eventName, funct, false); 
    } 

    if(!el.eventHolder) el.eventHolder = []; 
    el.eventHolder[el.eventHolder.length] = new Array(eventName, funct); 
} 

DomLib.prototype.removeEvent = function (obj, type, fn) { 
    if (obj.detachEvent) { 
    obj.detachEvent('on'+type, obj[type+fn]); 
    obj[type+fn] = null; 
    } else { 
    obj.removeEventListener(type, fn, false); 
    } 
} 


DomLib.prototype.hasEventEx = function (el, eventName, funct) { 

    if (!el.eventHolder) { 
    return false; 
    } else { 
    for (var i = 0; i < el.eventHolder.length; i++) { 
     if (el.eventHolder[i][0] == eventType && String(el.eventHolder[i][1]) == String(funct)) { 
     return true; 
     } 
    } 
    } 
    return false; 
} 

/** 
* @return - returns true if an event was removed 
*/ 
DomLib.prototype.removeEventsByTypeEx = function (el, eventType) { 

    if (el.eventHolder) { 

    var removed = 0; 
    for (var i = 0; i < el.eventHolder.length; i++) { 
     if (el.eventHolder[i][0] == eventType) {     
     this.removeEvent(el, eventType, el.eventHolder[i][1]); 
     el.eventHolder.splice(i, 1); 
     removed++; 
     i--; 
     } 
    } 

    return (removed > 0) ? true : false; 
    } else { 
    return false; 
    } 
} 

Testing HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html> 
<head> 
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT"> 
<meta http-equiv="Pragma" content="no-cache"> 
<meta http-equiv="Cache-Control" content="no-cache"> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<meta http-equiv="Lang" content="en"> 
<meta name="author" content=""> 
<meta http-equiv="Reply-to" content="@.com"> 
<meta name="generator" content="PhpED 5.8"> 
<meta name="description" content=""> 
<meta name="keywords" content=""> 
<meta name="creation-date" content="01/01/2009"> 
<meta name="revisit-after" content="15 days"> 
<title>DomLibTest</title> 
<link rel="stylesheet" type="text/css" href="my.css"> 
<!-- FILL IN: Location of your jQuery library --> 
<script type="text/javascript" src="jQuery/jQuery-current.js"></script> 
<!-- FILL IN: Plugin for debugging ... http://www.ecitadel.net/blog/2009/12/08/developing-jquery-use-dump-instead-alert --> 
<script type="text/javascript" src="jQuery/jQuery.dump.js"></script> 
<script type="text/javascript" src="DomLib.js"></script> 
</head> 
<body> 

    <div id="testElem-1"></div> 
    <script type="text/javascript"> 
    <!-- 

    var domLib = new DomLib(); 

    function removeTest(el) { 

     var funct = function() { alert("#1: How Are You?");}; 
     var funct2 = function() { alert("#2: How Are You?");};     

     domLib.regEventEx(el, "click", funct); 
     domLib.regEventEx(el, "mousemove", funct2); 
     domLib.regEventEx(el, "mousemove", funct2); 
     domLib.regEventEx(el, "mousemove", funct2); 

     $.dump(el.eventHolder);  
     domLib.removeEventsByTypeEx(el, "mousemove");  
     $.dump(el.eventHolder); 
    } 

    removeTest(document.getElementById('testElem-1')); 

    --> 
    </script> 
</body> 
</html> 
5

Secondo this thread, è possibile utilizzare cloneNode mettere a nudo tutti i listener di eventi da un elemento di javascript, in questo modo:

var new_element = old_element.cloneNode(true); 
old_element.parentNode.replaceChild(new_element, old_element); 
+1

Sì, ma la seguente frase è: Credo che attachEvent persiste anche quando un elemento è clonato, quindi non sono sicuro di cosa faresti per gli utenti di Internet Explorer. –

8

Potrebbe essere una buona idea usare jQuery o un framework simile per gestire tutti i gestori di eventi. Questo vi darà l'uso di facile, funzioni discreti per aggiungere e rimuovere i gestori di eventi:

$(...).bind('click', function() { ... }); 
$(...).unbind('click'); 
// or, to unbind all events: 
$(...).unbind(); 
+0

Mi piacerebbe capire come funziona. Memorizza semplicemente le funzioni da qualche parte e unbind() semplicemente passa attraverso l'elenco delle funzioni e chiama removeEventListener? –

+2

Memorizza internamente un elenco eventi – ThiefMaster

+0

'$ (" * "). Unbind();' rimuoverà tutti gli Event Handler di tutti gli elementi, se si sta tentando di farlo. – palswim

-6

Per quanto ne so, non è possibile aggiungere due gestori onclick di un elemento a tutti.

Supponiamo che obj sia un elemento, quindi la proprietà onclick di obj è considerata una funzione e quindi viene chiamata come metodo ogni volta che si verifica quell'evento. Se non è una funzione, non accadrà nulla.

JavaScript ereditato da Scheme una proprietà molto interessante, in JavaScript, non si definiscono funzioni come in PHP o C. Si creano funzioni anonime e si memorizzano in una variabile. Javascript è 'Lisp-1', non ci sono identificatori di funzione, ci sono variabili, che possono contenere numeri, matrici e funzioni.

function name(arg) {return arg;} 

è che se non sbaglio veramente zucchero per:

name = function(arg) {return arg;}; 

'nome' qui è una variabile, possiamo anche ri-Asign non importa quanto abbiamo definito tale funzione. A differenza del modello a oggetti di Java, in Javascript, un "metodo" è puramente una proprietà, una variabile che contiene semplicemente una funzione che può o non può utilizzare la parola chiave "this". Questo è il motivo per cui non puoi avere due eventi onclick allo stesso tempo. L'ambiente runtime chiama semplicemente la proprietà (che è prevista per ospitare una funzione) dell'elemento chiamato "onclick" ogni volta che si fa clic su di esso. Consideralo come lo stesso comportamento ad hoc del tipo di chiamata 'main' per avviare un programma.

Per assegnare più gestori di eventi, si utilizza una funzione con un effetto collaterale, come.

obj.onclick = function {firstEvent();secondEvent();} 

Per modificare o rimuoverlo, abbiamo riassegnare o de-assegna come qualsiasi variabile.

obj.onclick = null; 

E nel caso in cui abbiamo bisogno di invocare che il comportamento in un altro modo:

obj.onclick(); 

Possiamo anche usare questa in quella funzione, naturalmente, per modificare l'oggetto stesso o farvi riferimento.

Modifica: Oh aspetta, ora capisco che intendi con un pulsante molti pulsanti diversi.

Bene, poi basta raccogliere tutti gli elementi come:

allElements = document.getElementsByTagName('*'); 

e quindi si utilizza un ciclo:

var i = 0; while(obj = allElements[i++]) obj.onclick = null; 

(e no, che i singoli = non è un errore di battitura)

+0

http://pastebin.org/237133 - questo è un esempio di codice che chiama due gestori onclick per un pulsante. (Testato su Firefox e Chrome) –

+0

In realtà solo un pulsante non è molti. –

+4

-1 disinformazione nella prima frase. Scopri come funziona la gestione degli eventi in JavaScript e correggi il post per renderlo un +1 – naugtur

0

Combinando alcuni modi insieme, compresa l'individuazione e la rimozione di tutti i "sul ..." evento attributi dalla lista di attributi dell'elemento, altrimenti si sta rimuovendo solo il DOM funzione-gestori ...

icompile.eladkarako.com/force-chrome-password-saving-by-removing-event-handlers-the-jsninja-way/

siete i benvenuti per aggiungere tutti i vostri moo/jQuery altro quadro/dal seguente non ha dipendenze in una di queste (diamine! se anche dovrebbe funzionare in IE)

6

Se avete solo elemento di un bambino sotto i genitori del vostro elemento (o se non vi occupate di gestori di eventi tutti di pari livello ha perso troppo):

elem.parentElement.innerHTML = elem.parentElement.innerHTML; 

Testato in Chrome 49, FF 44, IE 11

Rimuove tutti i 'addEventListener'-s.

Problemi correlati