2010-05-14 10 views
32

Me gustaría eliminar TODOS los controladores para un tipo de evento dado. Supongamos que agregué dos veces "evento onclick" a un botón y ahora me gustaría volver al estado original donde no se configuró ningún controlador de eventos en el botón.¿Es posible eliminar todos los controladores de eventos de un elemento determinado en javascript?

¿Cómo puedo hacer eso?

PD: He encontrado los métodos removeEventListener (non-IE)/detachEvent (IE) pero las funciones quieren que pase como parámetro la función que maneja el evento que me parece bastante torpe porque tendría que almacenar las funciones en alguna parte.

EDIT: http://ejohn.org/blog/flexible-javascript-events/ - Ahora estoy usando el código

+1

¿Está utilizando el atributo onclick en línea? – Mottie

+0

+1 Gran pregunta. –

+0

Una opción mejor y más directa es usar la solución de @jiggy http://stackoverflow.com/questions/803936/how-to-clear-remove-javascript-event-handler – chowey

Respuesta

7

http://www.quirksmode.org/js/events_advanced.html - "¿Qué controladores de eventos están registrados?" - parece que no es posible sin DOM nivel 3 :-(

EDIT: se me ha ocurrido con este código se adapte a mis necesidades Tal vez será útil para otra persona

Javascript:

... página
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; 
    } 
} 

Prueba 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

Según this thread, puede utilizar cloneNode para despojar a todos los detectores de eventos de un elemento de JavaScript, así:

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

Sí, pero la siguiente oración es: Creo que attachEvent persiste incluso cuando se clona un elemento, por lo que no estoy seguro de qué haría con los usuarios de Internet Explorer. –

8

Se podría sea ​​una buena idea usar jQuery o un marco similar para administrar todos los manejadores de eventos. Esto le dará el uso fácil de funciones discretas para añadir y eliminar controladores de eventos:

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

Me gustaría entender cómo funciona. ¿Simplemente almacena las funciones en algún lugar y desvincula() simplemente revisa la lista de funciones y llama a removeEventListener? –

+2

Almacena internamente una lista de eventos – ThiefMaster

+0

'$ (" * "). Unbind();' eliminará todos los manejadores de eventos de todos los elementos, si está intentando hacer eso. – palswim

-6

Por lo que yo sé, no se puede agregar dos manipuladores onclick de un elemento en absoluto.

Say obj es un elemento, luego la propiedad onclick de obj se considera una función y luego se llama como método cada vez que se produce ese evento. Si no es una función, no pasará nada.

JavaScript heredado de Scheme una propiedad muy interesante, en JavaScript no define funciones como en PHP o C. Crea funciones anónimas y las almacena en una variable. Javascript es 'Lisp-1', no hay identificadores de funciones, hay variables que pueden contener números, matrices y funciones.

function name(arg) {return arg;} 

es que si no me equivoco verdaderamente azúcar para:

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

'nombre' aquí es una variable, también puede volver a asign que no importa cómo definimos esa función. A diferencia del modelo de objetos de Java, en Javascript, un 'método' es puramente una propiedad, una variable que simplemente contiene una función que puede o no usar la palabra clave 'this'. Es por eso que no puede tener dos eventos onclick al mismo tiempo. El entorno de tiempo de ejecución simplemente llama a la propiedad (que se espera albergue una función) del elemento llamado 'onclick' cada vez que hace clic en él. Véalo como el mismo comportamiento tipo ad hoc de invocar 'main' para iniciar un programa.

Para asignar múltiples controladores de eventos, utiliza una función con un efecto secundario, como.

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

Para cambiarlo o quitarlo, lo reasignamos o desasignamos como cualquier variable.

obj.onclick = null; 

Y en caso de que tengan que invocar que el comportamiento de otra manera:

obj.onclick(); 

También podemos utilizar esto en función de que, por supuesto, cambiar el objeto en sí mismo o hacer referencia a ella.

Editar: Oh, espera, ahora veo que te refieres a un botón con muchos botones diferentes.

Bueno, entonces usted acaba de recoger todos los elementos como:

allElements = document.getElementsByTagName('*'); 

Y a continuación, utiliza un bucle:

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

(y no, que = único no es un error tipográfico)

+0

http://pastebin.org/237133 - este es un ejemplo de un código que llama a dos manejadores onclick por un botón. (Probado en Firefox y Chrome) –

+0

I realmente solo un botón no muchos. –

+4

-1 información errónea en la primera oración. Descubra cómo funciona el manejo de eventos en JavaScript y corrija la publicación para convertirlo en un +1 – naugtur

0

combinar algunas de las formas en conjunto, incluyendo la búsqueda y eliminación de todos los "en ..." event-atributos de lista de atributos del elemento, de lo contrario va a extraer solamente el DOM de función manipuladores ...

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

son muy bienvenidos a añadir toda tu moo/jQuery/otro marco ya la siguiente no tiene dependencias en cualquiera de los (diablos! Si aún deben trabajar en IE)

6

Si sólo tiene un elemento de un niño menor de padres de su elemento (o si no te importa controladores de eventos todo de hermanos perdieron también):

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

Probado en Chrome 49, FF 44, IE 11

Elimina todos los 'addEventListener'-s.

Cuestiones relacionadas