2011-07-09 11 views

Respuesta

12

FileReader tiene métodos como addEventHandler porque es defined para implementar la interfaz EventTarget. EventTarget está definido por la especificación DOM Events, pero no necesita ser un objeto DOM para implementarlo. window, XMLHttpRequest y FileReader son otros objetos del Modelo de objetos del navegador que implementan EventTarget.

Lamentablemente, no hay una manera fácil de aprovechar la implementación nativa del navegador de objetivos de eventos ... podría intentar heredar de un objeto del navegador utilizando una propiedad como prototype, pero eso es muy poco fiable en general. Sin embargo, no es demasiado difícil de escribir código para implementar todos los métodos a sí mismo en la llanura de JavaScript:

function CustomEventTarget() { this._init(); } 

CustomEventTarget.prototype._init= function() { 
    this._registrations= {}; 
}; 
CustomEventTarget.prototype._getListeners= function(type, useCapture) { 
    var captype= (useCapture? '1' : '0')+type; 
    if (!(captype in this._registrations)) 
     this._registrations[captype]= []; 
    return this._registrations[captype]; 
}; 

CustomEventTarget.prototype.addEventListener= function(type, listener, useCapture) { 
    var listeners= this._getListeners(type, useCapture); 
    var ix= listeners.indexOf(listener); 
    if (ix===-1) 
     listeners.push(listener); 
}; 

CustomEventTarget.prototype.removeEventListener= function(type, listener, useCapture) { 
    var listeners= this._getListeners(type, useCapture); 
    var ix= listeners.indexOf(listener); 
    if (ix!==-1) 
     listeners.splice(ix, 1); 
}; 

CustomEventTarget.prototype.dispatchEvent= function(evt) { 
    var listeners= this._getListeners(evt.type, false).slice(); 
    for (var i= 0; i<listeners.length; i++) 
     listeners[i].call(this, evt); 
    return !evt.defaultPrevented; 
}; 

Precaución: el código anterior es la parte superior de la cabeza y no probado, pero puede funcionar. Sin embargo, tiene limitaciones como solo admitir el valor de retorno dispatchEvent si el objeto Event admite la propiedad DOM Level 3 defaultPrevented, y no admite DOM Level 3 stopImmediatePropagation() (que es imposible de implementar a menos que dependa de su propio objeto Event que expone una propiedad para eso). Además, no hay implementación de jerarquía o captura/burbujeo.

Por lo tanto, IMO: no gana mucho tratando de escribir el código que participa en el modelo de eventos DOM. Para el trabajo de devolución de llamada simple-JS, simplemente iría con su propia implementación ad hoc de listener-lists.

+0

Obtuve mi propio modelo de eventos: una función que vincula a los manejadores a un "tipo de evento", almacenándolos en un hash y una función que desencadena "eventos" en objetos que heredan este modelo (y algunos otros métodos de utilidad). ¿Dice que el modelo de evento predeterminado no tiene ningún beneficio valioso sobre el mío? – jayarjo

+1

Sí, los beneficios son bastante pequeños, diría que no se puede ser 100% interoperable con otras implementaciones de 'Evento' debido a que no se puede leer con certeza si' preventDefault'/'stopPropagation' /' stopImmediatePropagation' tiene sido llamado. Entonces, el único beneficio es la familiaridad de la interfaz de eventos DOM ... pero podría decirse que es una interfaz bastante torpe. – bobince

+1

Me he topado con este: http://www.w3.org/TR/DOM-Level-3-Events/#interface-CustomEvent, donde el W3C lo recomienda para crear tipos de eventos específicos de la aplicación. Por lo que veo, aún no tiene un amplio respaldo, pero parece que allí es donde se dirige todo. – jayarjo

0

Supongo que es javascript; normalmente cualquier objeto que pueda obtener una referencia a un elemento DOM debería ser capaz de enviar un evento utilizando la función element.dispatchEvent; ver:

https://developer.mozilla.org/en/DOM/document.createEvent

https://developer.mozilla.org/en/DOM/element.dispatchEvent

+0

Sí, llegó aquí desde estas páginas. Quiero decir que FileReader no parece estar relacionado con ningún elemento DOM, o tiene una referencia a él. Pero al mismo tiempo tiene un método dispatchEvent en sí mismo y puede enviar eventos (eventos DOM, supongo). Un poco confuso ¿no? Me preguntaba si había una manera de crear un objeto con propiedades similares. – jayarjo

+0

Bueno, no tengo ninguna aplicación de FileReader a la mano, por lo que es solo una especulación, pero si el elemento DOM se mantuvo internamente como un método privado, y el dispatchEvent de FileReader solo reenvió la llamada al dispatchEvent of the internal Elemento DOM, ¿cómo lo sabríamos? – phtrivier

+0

¿Qué quiere decir con elemento DOM interno? ¿Hay un término del mundo real como este o estás especulando de nuevo? :) Supongo que si hubiera elementos DOM internos, entonces FileReader no necesitaría reenviar nada. Podría ser el mismo. – jayarjo

1

jQuery puede enviar eventos desde objetos comunes. Here's a fiddle.

function MyClass() { 
    $(this).on("MyEvent", function(event) { 
     console.log(event); 
    }); 

    $(this).trigger("MyEvent"); 
} 

var instance = new MyClass(); 
Cuestiones relacionadas