2010-05-14 5 views
32

Ich möchte ALLE Handler für einen bestimmten Ereignistyp entfernen. Nehmen wir an, ich habe zweimal einen "onclick-Event" zu einer Schaltfläche hinzugefügt und möchte jetzt zu dem ursprünglichen Zustand zurückkehren, in dem kein Event-Handler auf die Schaltfläche gesetzt wurde.Ist es möglich, alle Event-Handler eines bestimmten Elements in Javascript zu entfernen?

Wie kann ich das tun?

PS: Ich habe removeEventListener (nicht-IE)/detachEvent (IE) Methoden gefunden, aber die Funktionen wollen, dass ich als Parameter die Funktion übergeben, die das Ereignis behandelt, das mir ziemlich ungeschickt erscheint, weil ich speichern müsste die Funktionen irgendwo.

EDIT: http://ejohn.org/blog/flexible-javascript-events/ - ich bin jetzt mit diesen Code

+1

Verwenden Sie das Inline-onclick-Attribut? – Mottie

+0

+1 Große Frage. –

+0

Eine bessere, direktere Möglichkeit ist es, @ jiggy's Lösung zu verwenden http://stackoverflow.com/questions/803936/how-to-clear-remove-javascript-event-handler – chowey

Antwort

7

http://www.quirksmode.org/js/events_advanced.html - "Welche Event-Handler sind registriert?" - es scheint, es ohne DOM-3-Ebene nicht möglich ist :-(

EDIT: ich mit diesem Code habe kommen Es passt meine Bedürfnisse Vielleicht wird es für jemand anderen nützlich sein

Javascript:

...
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-Seite:

<!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

Nach this thread Sie cloneNode können alle Ereignis-Listener von einem JavaScript-Element abzustreifen, etwa so:

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

Ja, aber der folgende Satz ist: Ich glaube das attachEvent bleibt auch bestehen, wenn ein Element geklont wird. Daher bin ich mir nicht sicher, was Sie für Internet Explorer-Benutzer tun würden. –

8

Es könnte Es empfiehlt sich, jQuery oder ein ähnliches Framework zu verwenden, um alle Ereignishandler zu verwalten. Dies wird Ihnen einfach zu bedienende, unaufdringliche Funktionen hinzuzufügen und Event-Handler zu entfernen:

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

Ich würde gerne verstehen, wie es funktioniert. Speichern Sie einfach die Funktionen irgendwo und unbind() einfach durch die Liste der Funktionen gehen und removeEventListener aufrufen? –

+2

Es speichert intern eine Ereignisliste – ThiefMaster

+0

'$ (" * "). Unbind();' wird alle Event-Handler aller Elemente entfernen, wenn Sie dies versuchen. – palswim

-6

Soweit ich weiß, kann man nicht an allen zwei Onclick-Handler auf ein Element hinzuzufügen.

Say obj ist ein Element, dann wird die Eigenschaft onclick von obj als eine Funktion betrachtet und dann als Methode aufgerufen, wenn dieses Ereignis eintritt. Wenn es keine Funktion ist, wird nichts passieren.

JavaScript geerbt von Scheme eine sehr interessante Eigenschaft, in JavaScript, definieren Sie keine Funktionen wie in PHP oder C. Sie erstellen anonyme Funktionen und speichern sie in einer Variablen. Javascript ist 'Lisp-1', es gibt keine Funktionsbezeichner, es gibt Variablen, die Zahlen, Arrays und Funktionen enthalten können.

function name(arg) {return arg;} 

ist, wenn ich nicht wirklich Zucker täuscht für:

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

‚name‘ hier ist eine Variable, können wir auch wieder asign es egal, wie wir diese Funktion definiert. Im Gegensatz zum Objektmodell von Java ist eine "Methode" in Javascript eine reine Eigenschaft, eine Variable, die einfach eine Funktion enthält, die das Schlüsselwort "this" möglicherweise nicht verwendet. Aus diesem Grund können Sie nicht gleichzeitig zwei onclick-Ereignisse haben. Die Laufzeitumgebung ruft einfach die Eigenschaft (die erwartungsgemäß eine Funktion enthält) des Elements mit dem Namen 'onclick' auf, wenn Sie darauf klicken. Sehen Sie es als das gleiche Ad-hoc-Verhalten des Aufrufs von 'main' an, um ein Programm zu starten.

Um mehrere Event-Handler zuzuweisen, verwenden Sie eine Funktion mit einem Nebeneffekt, wie.

Um es zu ändern oder zu entfernen, weisen wir es wie jede Variable neu oder ab.

obj.onclick = null; 

Und für den Fall brauchen wir dieses Verhalten in einer anderen Art und Weise aufzurufen:

obj.onclick(); 

Wir können dies auch in dieser Funktion natürlich nutzen das Objekt selbst oder auf sie verweisen zu ändern.

Edit: Oh, Moment mal, ich sehe jetzt, dass Sie mit einem Knopf viele verschiedene Tasten meinen.

Na, dann sammeln Sie einfach alle Elemente wie:

allElements = document.getElementsByTagName('*'); 

Und dann verwenden Sie eine Schleife:

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

(und nein, das einzelne = ist kein Tippfehler)

+0

http://pastebin.org/237133 - Dies ist ein Beispiel für einen Code, der zwei Onclick-Handler für eine Schaltfläche aufruft. (Getestet in Firefox und Chrome) –

+0

Ich habe wirklich nur eine einzige Taste nicht viele. –

+4

-1 Fehlinformation im ersten Satz. Erfahren Sie, wie die Ereignisbehandlung in JavaScript funktioniert, und beheben Sie den Beitrag, um +1 zu erhalten – naugtur

0

paar Möglichkeiten zusammen Kombination, einschließlich der Suche und alle "auf ..." Event-Attribute aus der Attributliste des Elements, sonst entfernen Sie entfernen nur die DOM-Funktion-Handler ...

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

Sie sind herzlich eingeladen, alle Ihre moo/jQuery/anderen Rahmen, da die folgenden hinzuzufügen hat keine Abhängigkeiten in einem dieser (Heck! wenn sollte auch im IE funktionieren)

6

Wenn Sie nur ein untergeordnetes Element haben unter Elternteil Ihres Elements (oder, wenn Sie nicht Event-Handler ist alles Geschwister verlor auch) dagegen:

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

Getestet in Chrome 49, FF 44, IE 11

Es entfernt alle 'addEventListener'-s.

Verwandte Themen