Desarrollé algunas páginas mejoradas con javascript que funcionan bien en Firefox y Safari recientes. Me perdí de comprobar en Internet Explorer, y ahora encuentro que las páginas no funcionan en IE 6 y 7 (hasta ahora). Los scripts de alguna manera no se ejecutan, las páginas se muestran como si javascript no estuviera allí, aunque se ejecuta algo de javascript. Estoy usando bibliotecas propias con manipulación de dom, de YUI 2 uso YUI-Loader y XML-Http-Request, y en una página uso "psupload", que depende de JQuery.
Estoy instalando Microsoft Script Editor desde Office XP y ahora depuraré. También escribiré pruebas específicas ahora.
¿Cuáles son los puntos de falla típicos de IE? En qué dirección puedo mantener los ojos abiertos.
Encontré esta página, que muestra algunas diferencias. visita: Quirksmode
¿Puede, por su experiencia, nombrar algunas cosas típicas que debería buscar primero?
También haré más preguntas aquí para tareas específicas más adelante, pero por ahora estoy interesado en su experiencia por qué IE generalmente falla en scripts que funcionan bien en Firefox
Editar: ¡ Gracias por todas esas excelentes respuestas!
Mientras tanto, he adaptado todo el código para que también funcione con Internet Explorer. Integré jQuery y construí mis propias clases sobre él ahora. Este fue mi error básico, que no construí todas mis cosas en jQuery desde el principio. Ahora tengo.
También JSLint me ayudó mucho.
Y muchos de los problemas individuales de las diferentes respuestas ayudaron.
fuente
Respuestas:
No dude en actualizar esta lista si ve algún error u omisión, etc.
Nota: IE9 corrige muchos de los siguientes problemas, por lo que gran parte de esto solo se aplica a IE8 y versiones anteriores y, hasta cierto punto, IE9 en modo peculiar. Por ejemplo, IE9 soporta SVG,
<canvas>
,<audio>
y<video>
de forma nativa, sin embargo se debe habilitar el modo de cumplimiento de normas para que estén disponibles.General:
Problemas con documentos parcialmente cargados: es una buena idea agregar su JavaScript en un
window.onload
evento o similar, ya que IE no admite muchas operaciones en documentos parcialmente cargados.Atributos diferentes : en CSS, está
elm.style.styleFloat
en IE frente aelm.style.cssFloat
en Firefox. En las<label>
etiquetas,for
se accede al atributoelm.htmlFor
en IE vselm.for
en Firefox. Tenga en cuenta quefor
está reservado en IE, porelm['for']
lo que probablemente sea una mejor idea evitar que IE genere una excepción.Lenguaje base de JavaScript:
Acceder a caracteres en cadenas :
'string'[0]
no es compatible con IE ya que no está en las especificaciones originales de JavaScript. Use'string'.charAt(0)
o'string'.split('')[0]
tenga en cuenta que acceder a elementos en matrices es significativamente más rápido que usarcharAt
con cadenas en IE (aunque hay una sobrecarga inicial cuandosplit
se llama por primera vez).Comas antes del final de los objetos: por ejemplo
{'foo': 'bar',}
, no se permiten en IE.Problemas específicos del elemento:
Obteniendo el
document
de un IFrame :IFrame.contentDocument
(IE comenzó a admitir esto desde la versión 8 ).IFrame.contentWindow.document
IFrame.contentWindow
refiere awindow
en ambos navegadores).Canvas: las versiones de IE anteriores a IE9 no admiten el
<canvas>
elemento. IE admite VML, que es una tecnología similar, sin embargo, explorercanvas puede proporcionar un contenedor in situ para<canvas>
elementos para muchas operaciones. Tenga en cuenta que IE8 en el modo de cumplimiento de estándares es muchas veces más lento y tiene muchos más fallos que en el modo de peculiaridades cuando se usa VML.SVG: IE9 admite SVG de forma nativa. IE6-8 puede admitir SVG, pero solo con complementos externos y solo algunos de esos complementos admiten la manipulación de JavaScript.
<audio>
y<video>
: solo se admiten en IE9.Creación dinámica de botones de
document.createElement
opción : IE <8 tiene un error que hace que los botones de opción creados con no se puedan marcar. Consulte también ¿Cómo se crea dinámicamente un botón de opción en Javascript que funcione en todos los navegadores? para una forma de evitar esto.JavaScript incrustado en
<a href>
etiquetas yonbeforeunload
conflictos en IE: si hay JavaScript incrustado en lahref
parte de unaa
etiqueta (por ejemplo<a href="javascript: doStuff()">
, IE siempre mostrará el mensaje devuelto aonbeforeunload
menos que elonbeforeunload
controlador se elimine de antemano. Consulte también Solicitar confirmación al cerrar una pestaña .<script>
diferencias de evento de etiqueta:onsuccess
yonerror
no son compatibles con IE y se reemplazan por un IE específicoonreadystatechange
que se activa independientemente de si la descarga se realizó correctamente o no. Consulte también JavaScript Madness para obtener más información.Tamaño / posición / desplazamiento del elemento y posición del mouse:
Obtener el tamaño / posición del elemento: el ancho / alto de los elementos a veces está
elm.style.pixelHeight/Width
en IE en lugar deelm.offsetHeight/Width
, pero ninguno es confiable en IE, especialmente en modo peculiar, y a veces uno da un mejor resultado que el otro.elm.offsetTop
y aelm.offsetLeft
menudo se informan incorrectamente, lo que lleva a encontrar que las posiciones de los elementos son incorrectas, razón por la cual los elementos emergentes, etc., tienen algunos píxeles de diferencia en muchos casos.También tenga en cuenta que si un elemento (o un padre del elemento) tiene una
display
de,none
entonces IE generará una excepción al acceder a los atributos de tamaño / posición en lugar de regresar0
como lo hace Firefox.Obtenga el tamaño de la pantalla (obteniendo el área visible de la pantalla):
window.innerWidth/innerHeight
document.documentElement.clientWidth/clientHeight
document.body.clientWidth/clientHeight
Posición de desplazamiento del documento / posición del mouse : este en realidad no está definido por el w3c, por lo que no es estándar ni siquiera en Firefox. Para encontrar el
scrollLeft
/scrollTop
dedocument
:document.body.scrollLeft/scrollTop
document.documentElement.scrollLeft/scrollTop
NOTA: Algunos otros navegadores también usan
pageXOffset
/pageYOffset
.Para obtener la posición del cursor del mouse,
evt.clientX
yevt.clientY
en losmousemove
eventos, dará la posición relativa al documento sin agregar la posición de desplazamiento, por lo que será necesario incorporar la función anterior:Selecciones / rangos:
<textarea>
y<input>
selecciones :selectionStart
yselectionEnd
no están implementadas en IE, y hay un sistema de "rangos" propietario en su lugar, vea también la posición de Caret en textarea, en caracteres desde el principio .Obtener el texto seleccionado actualmente en el documento:
window.getSelection().toString()
document.selection.createRange().text
Obtener elementos por ID:
document.getElementById
también puede hacer referencia alname
atributo en formularios (dependiendo de cuál se defina primero en el documento) por lo que es mejor no tener diferentes elementos que tengan el mismoname
yid
. Esto se remonta a los días en queid
no era un estándar de w3c.document.all
( una propiedad patentada específica de IE ) es significativamente más rápido quedocument.getElementById
, pero tiene otros problemas, ya que siempre priorizaname
antesid
. Yo personalmente uso este código, retrocediendo con verificaciones adicionales solo para estar seguro:Problemas con innerHTML de solo lectura:
IE no es compatible con el establecimiento de la innerHtml
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
, ytr
elementos. Aquí hay una función que funciona en torno a eso para los elementos relacionados con la tabla:También tenga en cuenta que IE requiere agregar a
<tbody>
a<table>
antes de agregar<tr>
s a ese<tbody>
elemento al crear usandodocument.createElement
, por ejemplo:Diferencias de eventos:
Obtener la
event
variable: los eventos DOM no se pasan a funciones en IE y son accesibles comowindow.event
. Una forma común de obtener el evento es usar, por ejemplo,elm.onmouseover = function(evt) {evt = evt||window.event}
el valor predeterminado
window.event
sievt
no está definido.Diferencias clave en el código de eventos: los códigos de eventos clave varían enormemente, aunque si nos fijamos en Quirksmode o JavaScript Madness , no es específico de IE, Safari y Opera son diferentes nuevamente.
Diferencias de eventos del mouse: el
button
atributo en IE es un indicador de bits que permite múltiples botones del mouse a la vez:var isLeft = evt.button & 1
)var isRight = evt.button & 2
)Centro: 4 (
var isCenter = evt.button & 4
)El modelo W3C (compatible con Firefox) es menos flexible que el modelo IE, con solo un botón permitido a la vez con la izquierda como
0
, la derecha como2
y el centro como1
. Tenga en cuenta que, como Peter-Paul Koch menciona , esto es muy contrario a la intuición, ya que0
por lo general significa 'ningún botón'.offsetX
yoffsetY
son problemáticos y probablemente sea mejor evitarlos en IE. Una forma más confiable de obtener eloffsetX
yoffsetY
en IE sería obtener la posición del elemento relativamente posicionado y restarlo declientX
yclientY
.También tenga en cuenta que en IE para conseguir un doble clic en un
click
evento que había necesidad de registrar la vez unaclick
ydblclick
eventos a una función. Firefox se disparaclick
al igual quedblclick
cuando se hace doble clic, por lo que se necesita una detección específica de IE para tener el mismo comportamiento.Las diferencias en el caso de modelo de manipulación: Tanto el modelo propietario IE y el modelo de manipulación de soporte Firefox de eventos de la parte inferior hacia arriba, por ejemplo, si hay eventos en ambos elementos de
<div><span></span></div>
eventos luego se disparará en elspan
entonces ladiv
lugar de la orden que están consolidado sielm.onclick = function(evt) {}
se utilizó un ejemplo tradicional .Los eventos de "captura" generalmente solo son compatibles con Firefox, etc., lo que activará
div
losspan
eventos en un orden de arriba hacia abajo. IE tieneelm.setCapture()
yelm.releaseCapture()
para redirigir los eventos del mouse del documento al elemento (elm
en este caso) antes de procesar otros eventos, pero tienen una serie de problemas de rendimiento y otros, por lo que probablemente deberían evitarse.Firefox:
Adjuntar :
elm.addEventListener(type, listener, useCapture [true/false])
Separar :
elm.removeEventListener(type, listener, useCapture)
(
type
por ejemplo,'mouseover'
sin elon
)IE: solo se puede agregar un evento de un tipo determinado en un elemento en IE; se genera una excepción si se agrega más de un evento del mismo tipo. También tenga en cuenta que se
this
refiere alwindow
elemento enlazado en lugar del elemento enlazado en las funciones de evento (por lo que es menos útil):Adjuntar :
elm.attachEvent(sEvent, fpNotify)
Separar :
elm.detachEvent(sEvent, fpNotify)
(
sEvent
es por ejemplo'onmouseover'
)Diferencias de atributos de eventos:
Evitar que los eventos sean procesados por otras funciones de escucha :
Firefox:
evt.stopPropagation()
IE:
evt.cancelBubble = true
Evite, por ejemplo, que los eventos clave inserten caracteres o impidan que las casillas de verificación se marquen:
Firefox:
evt.preventDefault()
IE:
evt.returnValue = false
Nota: Sólo volviendo
false
enkeydown
,keypress
,mousedown
,mouseup
,click
yreset
también evitar un impago.Obtenga el elemento que desencadenó el evento:
Firefox:
evt.target
IE:
evt.srcElement
Obtener el elemento del que se alejó el cursor del mouse:
evt.fromElement
en IE estáevt.target
en Firefox si es unonmouseout
evento, de lo contrarioevt.relatedTarget
Obtener el elemento al que se movió el cursor del mouse:
evt.toElement
en IE estáevt.relatedTarget
en Firefox si en unonmouseout
evento, de lo contrarioevt.target
Nota:
evt.currentTarget
(el elemento al que estaba vinculado el evento) no tiene equivalente en IE.fuente
Compruebe también si hay comas como estas o similares si las hay en su código
la última coma (después de value2) será tolerada por Firefox, pero no IE
fuente
Si sigues usando jQuery o YUI cuando tu publicación está etiquetada, deberías tener diferencias mínimas entre los navegadores ... para eso están los frameworks, para solucionar estas diferencias entre navegadores por ti.
Por ejemplo, mire la página de recorrido de DOM de quirksmode , según ella, IE no es compatible con la mayoría de las cosas ... aunque es cierto, los marcos sí, por ejemplo, IE no es compatible
elem.childElementCount
, pero en jQuery:$(elem).children().size()
funciona para obtener este valor, en todos los navegadores. Encontrará que hay algo en la biblioteca para manejar el 99% de los casos no compatibles en todos los navegadores, al menos con un script ... con CSS, es posible que tenga que pasar a complementos para la biblioteca, un ejemplo común de esto es obtener esquinas redondeadas trabajando en IE ... ya que no tiene soporte CSS para tal.Sin embargo, si empiezas a hacer las cosas directamente,
document.XXX(thing)
entonces no estás en la biblioteca, estás haciendo javascript directamente (todo es javascript, pero entiendes el punto :), y esto podría o no causar problemas, dependiendo de cómo borracho estaba el equipo de IE al implementar esa función en particular.Con IE, es más probable que falle en el estilo que sale bien que en problemas de javascript sin procesar, animaciones con unos pocos píxeles de diferencia y ese tipo de cosas, mucho más en IE6, por supuesto.
fuente
getElementbyID también coincidirá con el atributo de nombre en IE, pero no con otros navegadores, e IE seleccionará el que encuentre primero.
ejemplo:
fuente
Hay muchas cosas, pero una trampa en la que solía caer era que muchos navegadores aceptan JSON sin nombres entre comillas, mientras que ie6 e ie7 no.
Editar : para aclarar, esto es solo un problema cuando se requiere JSON real, a diferencia de un objeto literal. JSON es un subconjunto de la sintaxis literal del objeto y está diseñado como un formato de intercambio de datos (como XML), por lo que está diseñado para ser más exigente.
fuente
Diferentes compatibilidad con JavaScript
IE no admite (la mayoría de) las extensiones agregadas a JavaScript desde la 1.5.
Nuevo en 1.6
indexOf()
,lastIndexOf()
,every()
,filter()
,forEach()
,map()
,some()
for each ... in
- itera valores en lugar de nombres de propiedades.Nuevo en 1.7
[a,b] = [1,2]
let
yyeild
Nuevo en 1.8
reduce()
,reduceRight()
Algunas de estas cosas requieren que especifique un número de versión de JavaScript para ejecutar (que se romperá en IE), pero algunas cosas como
[1,2,3].indexOf(2)
pueden no parecer tan importantes, hasta que intente ejecutarlo en IEfuente
javascript
y (la implementación específica)JScript
, no las diferencias entreMozilla JavaScript(TM)
yJScript
. Podría ser mejor mostrar dónde se desvía IE de ES.Las principales diferencias entre JavaScript en IE y JavaScript en los navegadores modernos (por ejemplo, Firefox) se pueden atribuir a las mismas razones detrás de las diferencias en CSS / (X) HTML entre navegadores. En el pasado, no existía un estándar de facto; IE / Netscape / Opera pelearon una guerra territorial, implementando la mayoría de las especificaciones, pero también omitiendo algunas, así como haciendo especificaciones propietarias para obtener ventajas entre sí. Podría continuar, pero saltemos al lanzamiento de IE8: JavaScript se evitó / despreció durante años, y con el aumento de FF y el desprecio de webcomm, IE eligió centrarse principalmente en avanzar su CSS desde IE6 en adelante. Y básicamente dejó atrás el soporte DOM. El soporte DOM de IE8 bien podría ser el de IE6, que se lanzó en 2001 ... así que el soporte DOM de IE está casi una década por detrás de los navegadores modernos. Si tiene discrepancias de JavaScript específicas de un motor de diseño, lo mejor es atacarlo de la misma manera que abordamos los problemas de CSS; Apuntando a ese navegador. NO USE SNIFFING DEL NAVEGADOR, use la detección de funciones para olfatear su navegador / su nivel de soporte DOM.
JScript no es la propia implementación de IE de ECMAScript; JScript fue la respuesta de IE al JavaScript de Netscape, ambos existieron antes de ECMAScript.
En cuanto a los atributos de tipo en el elemento de script, type = "text / javascript" es el estándar predeterminado (al menos en HTML5), por lo que nunca necesitará un atributo de tipo a menos que su script no sea JavaScript.
En la medida en que IE no es compatible con innerHTML ... innerHTML fue inventado por IE y todavía hoy NO es un estándar DOM. Otros navegadores lo han adoptado porque es útil, por lo que puede usarlo en varios navegadores. En cuanto al cambio dinámico de tablas, MSDN dice "debido a la estructura específica requerida por las tablas, las propiedades innerText e innerHTML de la tabla y los objetos tr son de solo lectura". No sé cuánto de eso fue cierto inicialmente, pero claramente los navegadores modernos lo han descubierto al lidiar con las complejidades del diseño de tablas.
Recomiendo leer PPK en JavaScript Scripting DOM de Jeremy Keith, de Douglas Crockford : The Good Parts y JavaScript Beginning de Christian Hellman con Scripting DOM y Ajax para obtener una sólida comprensión de JavaScript.
En lo que respecta a Frameworks / Libraries, si aún no tiene un conocimiento sólido de JavaScript, debe evitarlos. Hace 2 años caí en la trampa de jQuery, y aunque pude realizar hazañas magníficas, nunca aprendí nada sobre codificar JavaScript correctamente. En retrospectiva, jQuery es un increíble juego de herramientas DOM, pero mi incapacidad para aprender los cierres adecuados, la herencia prototípica, etc., no solo hizo retroceder mi conocimiento personal, mi trabajo comenzó a tener grandes impactos de rendimiento porque no tenía ni idea de lo que estaba haciendo.
JavaScript es el idioma del navegador; Si usted es un ingeniero del lado del cliente / front-end, es de suma importancia que controle JavaScript. Node.js está trayendo JavaScript al máximo, veo inmensos avances a diario en su desarrollo; JavaScript del lado del servidor será un estándar en un futuro muy cercano. Menciono esto para enfatizar aún más cuán importante es JavaScript ahora y será.
JavaScript va a hacer más olas que Rails.
¡Feliz secuencia de comandos!
fuente
Algunos objetos nativos son de solo lectura sin que realmente parezcan serlo (puede escribir en ellos pero no tiene ningún efecto). Por ejemplo, un javascript avanzado común se basa en extender el
Element
objeto anulando los métodos del sistema, por ejemplo, cambiando Element.prototype.appendChild () para hacer más que agregar un nodo secundario, por ejemplo, inicializarlo con los datos de los padres. Esto fallará silenciosamente en IE6: el método original se invocará en los objetos nuevos en lugar del nuevo.Algunos navegadores (no recuerdo cuál ahora) consideran las nuevas líneas entre las etiquetas HTML como nodos de texto, mientras que otros no lo hacen. Entonces childNodes (n), nextSibling (), firstChild () y similares se comportarán de manera muy diferente.
fuente
Las comas finales en matrices y objetos literales solían ser un problema, no se han verificado recientemente (es decir, IE8):
Esto causaría algo de código adicional al generar dichas estructuras en el lado del servidor.
fuente
Acabo de encontrar uno esta mañana, un compañero de trabajo estableció la etiqueta del script como:
<script type="application/javascript">
porque su autocompletado de ide tenía eso antes de "text / javascript"Pero, resulta que IE simplemente ignora todo el script si usa "aplicación / javascript", necesita usar "texto / javascript"
fuente
<script>
Encontré una peculiaridad el otro día con Internet Explorer. Estaba usando YUI y reemplazando el contenido de un cuerpo de tabla () configurando el innerHTML
Esto funcionaría en todos los navegadores EXCEPTO IE. Finalmente descubrí que no se podía reemplazar el innerHTML de una tabla en IE. Tuve que crear un nodo usando YUI y luego agregar ese nodo.
¡Fue divertido descubrirlo!
fuente
<tbody>
etiquetas.Las comas adicionales y las comas faltantes solían ser un problema habitual en IE, mientras que funciona sin problemas en FF.
fuente
IE es muy estricto sobre la falta de ";" también suele ser eso.
fuente
Por lo que vale, acabo de encontrarme con este desagradable problema en <IE9
digamos que tienes un html como este:
y por alguna razón (tuve una buena) necesita recuperar todo el HTML en la tabla antes del último TR de cierre, puede intentar algo como esto:
<IE9 no devolverá nada (-1) aquí porque la variable tableHtml contiene todas las etiquetas html en mayúsculas y lastIndexOf distingue entre mayúsculas y minúsculas. Para evitar esto, tuve que lanzar un toLowerCase () antes de lastIndexOf.
fuente
IE no es un navegador moderno y solo sigue ECMAScript libremente.
fuente
Mencionaste jQuery con el que estoy menos familiarizado, pero como referencia general, y específicamente con Prototype, una cosa a tener en cuenta son las palabras reservadas / nombres de métodos en IE. Sé que lo que a menudo me molesta son cosas como:
someElement.appendChild(new Element('label',{ **for**: someInput.id }).update( someLabelText );
(new Element (tagName, propertyHash) es cómo se crean nuevos elementos en Protitype). En IE,
for:
debe ser'for':
, porquefor
es una palabra reservada. Lo que tiene mucho sentido, pero FireFox lo tolerará.Otro ejemplo:
someElement.wrap('div').addClassName('someClass')
(el
wrap
método en Prototype envuelve un elemento en otro) - En IE, en áreas de texto,wrap
es una propiedad yElement.wrap()
debe usarse en lugar de la versión metodizadaEstos son dos ejemplos que me vienen a la mente de mi experiencia. Se basan en un prototipo, pero el problema principal no es: Tenga cuidado con los métodos / etiquetas / identificadores que IE considera palabras reservadas pero que FireFox o Safari tolerarán.
fuente
El hecho es que IE no es compatible con JavaScript ... Es compatible con su propia implementación de ECMAScript: JScript ... que es algo diferente ...
fuente
El uso
console.log()
para enviar errores a la consola de errores de Firefox hará que sus scripts fallen en IE. Tengo que recordar quitarlos cuando pruebes en IE.fuente