2010-09-18 22 views
12

Tengo problemas para lograr que attachEvent funcione. En todos los navegadores compatibles con el controlador addEventListener, el código siguiente funciona como un hechizo, pero en IE es un desastre completo. Tienen su propia variación (incompleta) llamada attachEvent.attachEvent versus addEventListener

Ahora aquí está el trato. ¿Cómo hago para que el evento attachEvent funcione de la misma manera que lo hace addEventListener?

Aquí está el código:

function aFunction(idname) 
{ 
    document.writeln('<iframe id="'+idname+'"></iframe>'); 
    var Editor = document.getElementById(idname).contentWindow.document; 

    /* Some other code */ 

    if (Editor.attachEvent) 
    { 
     document.writeln('<textarea id="'+this.idname+'" name="' + this.idname + '" style="display:none">'+this.html+'</textarea>'); 
     Editor.attachEvent("onkeyup", KeyBoardHandler); 
    } 
    else 
    { 
     document.writeln('<textarea id="hdn'+this.idname+'" name="' + this.idname + '" style="display:block">'+this.html+'</textarea>'); 
     Editor.addEventListener("keyup", KeyBoardHandler, true); 
    } 
} 

Este llama a la función KeyBoardHandler que tiene este aspecto:

function KeyBoardHandler(Event, keyEventArgs) { 
    if (Event.keyCode == 13) { 
     Event.target.ownerDocument.execCommand("inserthtml",false,'<br />'); 
     Event.returnValue = false; 
    } 

    /* more code */ 
} 

no quiero utilizar cualquier marcos porque a) Estoy tratando de aprender y entender algo, y B) cualquier marco es solo una sobrecarga de código que voy a usar.

¡Cualquier ayuda es muy apreciada!

+0

Tiene un buen punto para tratar de aprender sin utilizar un marco para comprender el funcionamiento interno del JavaScript basado en navegador. Sin embargo, te sugiero que pases a usar frameworks para código de producción una vez que hayas dominado JavaScript de bajo nivel, no tiene mucho sentido reinventar la rueda (los frameworks son ampliamente probados con una variedad de navegadores, y una vez usted desarrolla su propio marco de trabajo, se pondrá grande de todos modos para solucionar las peculiaridades del navegador y evitar el código repetitivo en otro lugar de su código). Además, el navegador puede almacenar en caché JavaScript externo una vez para múltiples solicitudes. – Archimedix

+0

¿Qué estás tratando de hacer y qué está sucediendo ahora que está mal? – lincolnk

+0

Los marcos como jquery se parecen más a un estándar hoy en día, intentan hacer que la compatibilidad con navegadores cruzados sea real, use javascript cuando realmente desee hacer algo específico y desee un control total. –

Respuesta

0

Puede que sea mejor utilizar un marco de JavaScript como MooTools o jQuery de su elección para facilitar el soporte de navegadores cruzados. Para más detalles, véase también

puerto MooTools de partes de su código de ejemplo:

var Editor = $(idname).contentWindow.document; 
... 
$(document.body).grab(new Element('textarea', { 
    'id' : this.idname, 
    'name' : this.idname, 
    'style': 'display:none;', 
    'html' : this.html 
}); 
Editor.addEvent('keyup', KeyBoardHandler); 

Por cierto, es a propósito que utilice tanto idname y this.idname en el código de arriba?

+3

Gracias muchachos, pero no, gracias. ;-) Primero, estoy tratando de aprender algo aquí, en segundo lugar, no quiero una sobrecarga de código que no voy a usar. Entonces, por favor, no consejo sobre el marco externo, aunque entiendo la idea detrás de esto. –

+1

Me refiero a esto con las mejores intenciones, tal vez sería mejor no aprender las peculiaridades de los exploradores subyacentes, sino dedicar su tiempo a aprender conceptos de alto nivel como devoluciones de llamada, promesas, el patrón del módulo, currying, etc. los navegadores se estandarizan más, su ROI al aprender tales detalles disminuirá, mientras que aprender más ideas de JavaScript abstractas es igual de satisfactorio para aprender y al mismo tiempo equiparlo para otros idiomas y cosas diferentes en la pista. – iono

3

Simplemente use un marco como jQuery o prototipo. Para eso están ahí, esta es la razón exacta: ser capaces de hacer este tipo de cosas sin tener que preocuparse por la compatibilidad entre navegadores. Es super fácil de instalar ... basta con incluir un script js y añadir una línea de código ...

(editado sólo para que la Media Luna fresca)

Con un marco, el código es tan simple como. ..

<script type='text/javascript' src='jquery.js'></script> 
$('element').keyup(function() { 
    // stuff to happen on event here 
}); 
+0

en serio ... ir a recoger jQuery o algo así ... Solía ​​resistirlo por mucho tiempo ... un día me vi obligado a aprender hasta el punto de corregir algún código que lo utilizaba ... desde entonces ... Me pateo constantemente por no usarlo antes. La mejor invención desde el pan rebanado. –

+11

¡Por qué no le muestra al OP lo fácil que es hacer con jQuery o Prototype! "Solo usa jQuery" no es un tipo de respuesta. –

+1

feliz? No pensé en algo tan "increíblemente fácil" como para explicarlo, pero como quieres ser un asno como si fueras una especie de policía interweb ... p. - Gracias por el voto negativo, me alegro de haber hecho que tu día de santurronería sea un poco más brillante. –

2

Aquí es una función que utilizo para ambos navegadores:

function eventListen(t, fn, o) { 
    o = o || window; 
    var e = t+Math.round(Math.random()*99999999); 
    if (o.attachEvent) { 
     o['e'+e] = fn; 
     o[e] = function(){ 
      o['e'+e](window.event); 
     }; 
     o.attachEvent('on'+t, o[e]); 
    }else{ 
     o.addEventListener(t, fn, false); 
    } 
} 

Y usted puede utilizarlo como:

eventListen('keyup', function(ev){ 
    if (ev.keyCode === 13){ 
    ... 
    } 
    ... 
}, Editor) 
+1

¿Cómo sería el inverso 'detachEvent' /' removeEventListener'? (ya sabes, por el bien de la simetría). –

+0

Entonces, ¿cómo usaría el código anterior en este caso? Lo siento, algo así como un novato de JS. :/ –

+0

Extrañamente, nunca tuve que desconectarme en nuestra aplicación. No hay código disponible, entonces ... – Mic

2

Los diferentes navegadores procesarán los eventos de forma diferente. Algunos navegadores tienen burbujas de eventos que arrojan los controles donde algunos van hacia arriba. Para obtener más información acerca de que echar un vistazo a este documento W3C: http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

En cuanto a este ajuste, el parámetro "userCapture" false para el addEventListener tema específico hará que los eventos se comportan igual que Internet Explorer: https://developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer

+0

'useCapture' solo determina si el evento se dispara durante la secuencia de captura o burbuja. IE solo hace la secuencia de burbuja, por lo que 'false' se usa para compatibilidad. no cambiará el proceso del controlador. – lincolnk

7

El fuente de sus problemas es la función KeyBoardHandler.Específicamente, en IE Event los objetos no tienen una propiedad target: el equivalente es srcElement. Además, la propiedad returnValue de los objetos Event es solo de IE. Desea el método preventDefault() en otros navegadores.

function KeyBoardHandler(evt, keyEventArgs) { 
    if (evt.keyCode == 13) { 
     var target = evt.target || evt.srcElement; 
     target.ownerDocument.execCommand("inserthtml",false,'<br />'); 
     if (typeof evt.preventDefault != "undefined") { 
      evt.preventDefault(); 
     } else { 
      evt.returnValue = false; 
     } 
    } 

    /* more code */ 
} 
14

A continuación, se indica cómo hacer que esto funcione entre navegadores, solo como referencia.

var myFunction=function(){ 
    //do something here 
} 
var el=document.getElementById('myId'); 

if (el.addEventListener) { 
    el.addEventListener('mouseover',myFunction,false); 
    el.addEventListener('mouseout',myFunction,false); 
} else if(el.attachEvent) { 
    el.attachEvent('onmouseover',myFunction); 
    el.attachEvent('onmouseout',myFunction); 
} else { 
    el.onmouseover = myFunction; 
    el.onmouseout = myFunction; 
} 

ref: http://jquerydojo.blogspot.com/2012/12/javascript-dom-addeventlistener-and.html

0

Alguien anteriormente mencionado que ".. en objetos de eventos de IE no tienen una propiedad de destino: el equivalente es srcElemento ..." Pues bien, en IE11 no es tal objetivo.

Cuestiones relacionadas