2011-01-04 24 views
12

Utilizando el método .attachEvent() en IE, ¿cómo hacer referencia a que el objeto que llama (el elemento que desencadenó el evento) con this? En navegadores normales, usando .addEventListener, el var this apunta al elemento, mientras que en IE apunta al objeto .cómo hacer referencia al objeto que contiene ("este") usando attachEvent

lo necesito para trabajar con el siguiente código:

var element = //the element, doesn't matter how it is obtained 
element.addAnEvent = function(name, funct){ 
    if(element.addEventListener) // Works in NORMAL browsers... 
    else if(element.attachEvent){ 
    element.attachEvent("on"+name, funct); 
    //where the value of "this" in funct should point to "element" 
    } 
} 

acabo de hacer que el código de arriba, no es exactamente lo mismo que mi código, pero si funciona con él, entonces se trabaja conmigo !

Respuesta

15

De this quirksmode article con respecto a attachEvent:

  1. Eventos siempre burbuja, sin posibilidad de capturar.
  2. La función de gestión de eventos se referencia, no se copia, por lo que esta palabra clave siempre se refiere a la ventana y es completamente inútil.

El resultado de estas dos debilidades es que cuando surge un evento es imposible saber qué elemento HTML maneja actualmente el evento. Explico este problema más completamente en la página de orden de evento.

Dado que el modelo de adición de eventos de Microsoft solo es compatible con el Explorador 5 y versiones posteriores en Windows, no se puede usar para scripts entre navegadores. Pero incluso para las aplicaciones de Explorer-on-Windows, lo mejor es no usarlo, ya que el problema de burbujeo puede ser bastante desagradable en aplicaciones complejas.

No lo he probado, pero una posible solución puede ser envolver el controlador en una función anónima que llame a su controlador a través del funct.call().

else if(element.attachEvent){ 
    element.attachEvent("on"+name, function(){ funct.call(element) }); 
} 

Mis excusas para la solución no probada. No me gusta hacer eso, pero no puedo acceder fácilmente a IE ahora mismo.

+0

así que, en lugar de usarlo, ¿debería usar la forma clásica 'element.onevent = function'? (Ej. 'Element.onmouseup' ...) – JCOC611

+0

@ JCOC611: Acabo de actualizar mi respuesta. Mi solución de código potencial fue retrógrada la primera vez. Si eso no funciona, entonces sí, yo pensaría que la manera clásica sería un retroceso. – user113716

+0

Lo intenté antes, pero descubrí lo que hice mal. ¡Muchas gracias! Patrick ftw !!! XD – JCOC611

0

Encuéntrelo. Bueno, no puede usar Function.prototype.bind que se agrega en javascript 1.8.5, pero puede usar closure y Function.prototype.apply.

var element = //the element, doesn't matter how it is obtained 
element.addAnEvent = function(name, funct){ 
    if(element.addEventListener) // Works in NORMAL browsers... 
    //... 
    else if(element.attachEvent){ 
    element.attachEvent("on"+name, function() { 
     //call funct with 'this' == 'element' 
     return funct.apply(element, arguments); 
    }); 
    } 
} 
+0

D'oh, cómo extrañé que Patric lo hubiera respondido. – Hemlock

10

Si estás en IE, se puede obtener el objeto "llama", como usted lo llama, accediendo window.event.srcElement dentro de la función de controlador de eventos. Este objeto normalmente se conoce como el evento objetivo o fuente.

var funct = function(event) { 
    if (!event) { 
     event = window.event; 
    } 

    var callerElement = event.target || event.srcElement; 

    // Do stuff 
}; 

Este código no ha sido probado, pero debería desviarlo en la dirección correcta.

+0

Trabajando extremadamente suave. Gracias. – dotTutorials

0

creo que sería mejor para extender el Element object, a través de la cadena de prototipo, en lugar de añadir el método para cada elemento que desee añadir eventos a (funciona con todos los navegadores) ..

Element.prototype.addAnEvent = function(name, funct){ 
    if(this.addEventListener) // Works in NORMAL browsers... 
    { 
    this.addEventListener(name,funct, false); 
    } 
    else if(this.attachEvent){ 
    var _this = this; 
    this.attachEvent("on"+name, function(){funct.apply(_this);}); 
    //where the value of "this" in funct should point to "element" 
    } 
}; 

Esta manera de que funcione para todos los elementos actuales y futuras (y sólo tiene que ejecutar una vez).

+0

Sí, sé de prototipos JS. Aún así, mi código no requiere creación de prototipos. Estoy haciendo un equivalente de la función '$()' de jQuery. Además, apuesto a que la creación de prototipos no es totalmente compatible con los navegadores cruzados. – JCOC611

+0

@JCOC, el código anterior se ha probado en IE, FF, Chrome, Safari y Opera ... Pero solo estoy sugiriendo una alternativa ... Conoces los detalles y puedes decidir qué es lo mejor para tu caso :) –

+0

This won ' t trabajo en IE 7 o inferior. –

Cuestiones relacionadas