Desenvolvi algumas páginas aprimoradas com javascript que funcionam bem no Firefox e Safari recentes. Perdi o check-in do Internet Explorer e agora descobri que as páginas não funcionam no IE 6 e 7 (até agora). Os scripts não são executados de alguma forma, as páginas aparecem como se o javascript não estivesse lá, embora algum javascript seja executado. Estou usando bibliotecas próprias com manipulação de dom, da YUI 2 uso o YUI-Loader e o XML-Http-Request e em uma página uso "psupload", que depende do JQuery.
Estou instalando o Microsoft Script Editor a partir do Office XP e agora vou depurar. Também vou escrever testes específicos agora.
Quais são os pontos de falha típicos do IE? Em que direção posso manter meus olhos abertos.
Encontrei esta página, que mostra algumas diferenças. visita: Quirksmode
Você pode, por experiência própria, citar algumas coisas típicas que devo procurar primeiro?
Também farei mais perguntas aqui para tarefas específicas mais tarde, mas por enquanto estou interessado em sua experiência por que o IE geralmente falha em scripts que funcionam bem no Firefox
Edit: Obrigado por todas essas ótimas respostas!
Nesse ínterim, adaptei todo o código para que funcione também com o Internet Explorer. Eu integrei o jQuery e construí minhas próprias classes em cima dele agora. Este foi meu erro básico, que eu não construí todas as minhas coisas no jQuery desde o início. Agora eu tenho.
O JSLint também me ajudou muito.
E muitas das questões individuais das diferentes respostas ajudaram.
fonte
Respostas:
Sinta-se à vontade para atualizar esta lista se encontrar algum erro / omissão, etc.
Observação: o IE9 corrige muitos dos problemas a seguir, portanto, muito disso se aplica apenas ao IE8 e versões anteriores e, até certo ponto, ao IE9 no modo peculiar. Por exemplo, IE9 suporta SVG,
<canvas>
,<audio>
e<video>
de forma nativa, no entanto você deve habilitar o modo de cumprimento de normas para que eles estejam disponíveis.Geral:
Problemas com documentos parcialmente carregados: É uma boa ideia adicionar seu JavaScript em um
window.onload
evento ou semelhante, pois o IE não oferece suporte a muitas operações em documentos parcialmente carregados.Atributos diferentes : em CSS, é
elm.style.styleFloat
no IE eelm.style.cssFloat
no Firefox. Em<label>
tags, ofor
atributo é acessado comelm.htmlFor
no IE eelm.for
no Firefox. Observe quefor
é reservado no IE, portanto,elm['for']
é provavelmente uma ideia melhor impedir o IE de lançar uma exceção.Linguagem JavaScript base:
Acessar caracteres em strings :
'string'[0]
não é compatível com o IE, pois não está nas especificações originais do JavaScript. Use'string'.charAt(0)
ou'string'.split('')[0]
observe que acessar itens em arrays é significativamente mais rápido do que usarcharAt
com strings no IE (embora haja alguma sobrecarga inicial quandosplit
é chamado pela primeira vez).Vírgulas antes do final dos objetos: por exemplo,
{'foo': 'bar',}
não são permitidas no IE.Problemas específicos do elemento:
Obtendo o
document
de um IFrame :IFrame.contentDocument
(o IE passou a oferecer suporte a partir da versão 8 ).IFrame.contentWindow.document
IFrame.contentWindow
refere-se awindow
em ambos os navegadores).Canvas: as versões do IE antes do IE9 não suportam o
<canvas>
elemento. O IE oferece suporte a VML, que é uma tecnologia semelhante, e o explorercanvas pode fornecer um wrapper local para<canvas>
elementos de muitas operações. Esteja ciente de que o IE8 no modo de conformidade com os padrões é muitas vezes mais lento e tem muito mais falhas do que no modo quirks ao usar VML.SVG: IE9 oferece suporte nativo a SVG. O IE6-8 pode suportar SVG, mas apenas com plug - ins externos, com apenas alguns desses plug-ins com suporte para manipulação de JavaScript.
<audio>
e<video>
: são suportados apenas no IE9.Criação dinâmica de botões de opção: o IE <8 tem um bug que torna os botões de opção criados com não
document.createElement
verificáveis. Veja também Como você cria dinamicamente um botão de rádio em Javascript que funciona em todos os navegadores? para encontrar uma maneira de contornar isso.JavaScript embutido em
<a href>
tags eonbeforeunload
conflitos no IE: Se houver JavaScript embutido nahref
parte de umaa
tag (por exemplo<a href="javascript: doStuff()">
, o IE sempre mostrará a mensagem retornadaonbeforeunload
, a menos que oonbeforeunload
manipulador seja removido antes. Consulte também Solicitar confirmação ao fechar uma guia .<script>
diferenças de evento de tag:onsuccess
eonerror
não são compatíveis com o IE e são substituídos por um específico do IEonreadystatechange
que é disparado independentemente de o download ter sido bem-sucedido ou não. Veja também JavaScript Madness para mais informações.Tamanho / posição / rolagem do elemento e posição do mouse:
Obtendo o tamanho / posição do elemento : largura / altura dos elementos às vezes é
elm.style.pixelHeight/Width
no IE em vez deelm.offsetHeight/Width
, mas nenhum é confiável no IE, especialmente no modo quirks, e às vezes um dá um resultado melhor do que o outro.elm.offsetTop
eelm.offsetLeft
muitas vezes são relatados incorretamente, levando à localização incorreta dos elementos, razão pela qual os elementos pop-up etc. estão alguns pixels fora em muitos casos.Observe também que se um elemento (ou um pai do elemento) tiver um
display
denone
, o IE gerará uma exceção ao acessar os atributos de tamanho / posição em vez de retornar0
como o Firefox faz.Obtenha o tamanho da tela (Obtendo a área visível da tela):
window.innerWidth/innerHeight
document.documentElement.clientWidth/clientHeight
document.body.clientWidth/clientHeight
Posição de rolagem do documento / posição do mouse : Esta realmente não é definida pelo w3c, portanto, não é padrão, mesmo no Firefox. Para encontrar o
scrollLeft
/scrollTop
dodocument
:document.body.scrollLeft/scrollTop
document.documentElement.scrollLeft/scrollTop
NOTA: Alguns outros navegadores usam
pageXOffset
/pageYOffset
também.Para obter a posição do cursor do mouse,
evt.clientX
eevt.clientY
emmousemove
eventos dará a posição relativa ao documento sem adicionar a posição de rolagem, portanto, a função anterior deverá ser incorporada:Seleções / intervalos:
<textarea>
e<input>
seleções :selectionStart
eselectionEnd
não são implementados no IE, e há um sistema de "intervalos" proprietário em seu lugar, consulte também Posição do cursor em textarea, em caracteres desde o início .Obtendo o texto atualmente selecionado no documento:
window.getSelection().toString()
document.selection.createRange().text
Obtendo elementos por ID:
document.getElementById
também pode se referir aoname
atributo em formulários (dependendo do que for definido primeiro no documento), portanto, é melhor não ter elementos diferentes que tenham o mesmoname
eid
. Isso remonta aos dias em queid
não era um padrão w3c.document.all
( uma propriedade proprietária específica do IE ) é significativamente mais rápido do quedocument.getElementById
, mas tem outros problemas, pois sempre priorizouname
antesid
. Eu pessoalmente uso este código, recorrendo a verificações adicionais apenas para ter certeza:Problemas com innerHTML somente leitura:
O IE não suporta definir o innerHTML de
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
, etr
elementos. Esta é uma função que contorna isso para elementos relacionados à tabela:Observe também que o IE requer a adição de a
<tbody>
a<table>
antes de anexar<tr>
s a esse<tbody>
elemento ao criar usandodocument.createElement
, por exemplo:Diferenças de evento:
Obtendo a
event
variável: os eventos DOM não são passados para funções no IE e são acessíveis comowindow.event
. Uma forma comum de obter o evento é usar, por exemplo,elm.onmouseover = function(evt) {evt = evt||window.event}
qual padrão é
window.event
ifevt
é indefinido.Principais diferenças de código de evento: os códigos de evento-chave variam muito, embora se você olhar para Quirksmode ou JavaScript Madness , dificilmente será específico para o IE, Safari e Opera são diferentes novamente.
Diferenças de eventos do mouse: o
button
atributo no IE é um sinalizador de bits que permite vários botões do mouse ao mesmo tempo:var isLeft = evt.button & 1
)var isRight = evt.button & 2
)Centro: 4 (
var isCenter = evt.button & 4
)O modelo W3C (compatível com Firefox) é menos flexível do que o modelo IE, com apenas um único botão permitido por vez com esquerda como
0
, direita como2
e centro como1
. Observe que, como Peter-Paul Koch menciona , isso é muito contra-intuitivo, pois0
geralmente significa 'sem botão'.offsetX
eoffsetY
são problemáticos e provavelmente é melhor evitá-los no IE. Uma maneira mais confiável de obter ooffsetX
eoffsetY
no IE seria obter a posição do elemento relativamente posicionado e subtraí-lo declientX
eclientY
.Observe também que, no IE, para obter um clique duplo em um
click
evento, você precisa registrar um eventoclick
edblclick
em uma função. O Firefox disparaclick
e tambémdblclick
quando clica duas vezes, portanto, a detecção específica do IE é necessária para ter o mesmo comportamento.Diferenças no evento modelo de manipulação: Tanto o modelo IE proprietário e o modelo de manipulação de apoio Firefox de eventos a partir da parte inferior para cima, por exemplo, se existem eventos em ambos os elementos de
<div><span></span></div>
eventos, em seguida, irá desencadear naspan
então adiv
vez da ordem que eles são vinculado se um tradicional por exemploelm.onclick = function(evt) {}
foi usado.Os eventos de "captura" geralmente são suportados apenas no Firefox etc, o que acionará
div
osspan
eventos em uma ordem de cima para baixo. O IE temelm.setCapture()
eelm.releaseCapture()
para redirecionar eventos do mouse do documento para o elemento (elm
neste caso) antes de processar outros eventos, mas eles têm uma série de problemas de desempenho e, portanto, devem ser evitados.Raposa de fogo:
Anexar :
elm.addEventListener(type, listener, useCapture [true/false])
Desanexar :
elm.removeEventListener(type, listener, useCapture)
(
type
é, por exemplo,'mouseover'
sem oon
)IE: apenas um único evento de um determinado tipo em um elemento pode ser adicionado no IE - uma exceção é levantada se mais de um evento do mesmo tipo for adicionado. Observe também que
this
se refere a emwindow
vez de ao elemento vinculado em funções de evento (portanto, é menos útil):Anexar :
elm.attachEvent(sEvent, fpNotify)
Desanexar :
elm.detachEvent(sEvent, fpNotify)
(
sEvent
é por exemplo'onmouseover'
)Diferenças de atributo do evento:
Impeça que os eventos sejam processados por qualquer outra função de escuta :
Firefox:
evt.stopPropagation()
IE:
evt.cancelBubble = true
Impeça, por exemplo, que eventos importantes insiram caracteres ou que as caixas de seleção sejam marcadas:
Firefox:
evt.preventDefault()
IE:
evt.returnValue = false
Nota: Apenas retornando
false
emkeydown
,keypress
,mousedown
,mouseup
,click
ereset
também evitar padrão.Obtenha o elemento que acionou o evento:
Firefox:
evt.target
IE:
evt.srcElement
Obtendo o elemento do qual o cursor do mouse se afasta:
evt.fromElement
no IE éevt.target
no Firefox, se em umonmouseout
evento, caso contrárioevt.relatedTarget
Obtendo o elemento para o qual o cursor do mouse se move:
evt.toElement
no IE éevt.relatedTarget
no Firefox, se em umonmouseout
evento, caso contrárioevt.target
Nota:
evt.currentTarget
(o elemento ao qual o evento foi vinculado) não tem equivalente no IE.fonte
Verifique também se há vírgulas como essas ou semelhantes, se houver, em seu código
a última vírgula (seguindo o valor 2) será tolerada pelo Firefox, mas não pelo IE
fonte
Se você continuar usando jQuery ou YUI como sua postagem é marcada, você deve ter diferenças mínimas entre os navegadores ... é para isso que servem as estruturas, para cuidar dessas diferenças entre navegadores para você.
Por exemplo, olhe para a página de travessia do DOM quirksmode , de acordo com ela, o IE não suporta a maioria das coisas ... embora seja verdade, os frameworks sim, por exemplo, o IE não suporta
elem.childElementCount
, mas em jQuery:$(elem).children().size()
funciona para obter este valor, em cada navegador. Você descobrirá que há algo na biblioteca para lidar com 99% dos casos não suportados entre navegadores, pelo menos com script ... com CSS você pode ter que mover para plug-ins para a biblioteca, um exemplo comum disso é obter cantos arredondados trabalhando no IE ... já que não tem suporte CSS para tal.No entanto, se você começar a fazer as coisas diretamente, por exemplo
document.XXX(thing)
, não está na biblioteca, está fazendo javascript diretamente (é tudo javascript, mas você entendeu :), e isso pode ou não causar problemas, dependendo de como bêbado que a equipe do IE estava ao implementar essa função específica.Com o IE, é mais provável que você falhe em estilizar corretamente do que problemas brutos de javascript, animações com alguns pixels de diferença e esse tipo de coisa, muito mais no IE6, é claro.
fonte
getElementbyID também corresponderá ao atributo name no IE, mas não em outros navegadores, e o IE selecionará o que encontrar primeiro.
exemplo:
fonte
Existem muitas coisas, mas uma armadilha que eu costumava cair era que muitos navegadores aceitam JSON sem nomes entre aspas, enquanto ie6 e ie7 não.
Editar : para esclarecer, este é um problema apenas quando o JSON real é necessário, ao contrário de um literal de objeto. JSON é um subconjunto da sintaxe literal do objeto e é um formato de troca de dados (como XML), por isso é projetado para ser mais seletivo.
fonte
Suporte para JavaScript diferente
O IE não oferece suporte (a maioria) às extensões adicionadas ao JavaScript desde 1.5.
Novo em 1.6
indexOf()
,lastIndexOf()
,every()
,filter()
,forEach()
,map()
,some()
for each ... in
- itera valores em vez de nomes de propriedades.Novo em 1.7
[a,b] = [1,2]
let
eyeild
Novo em 1.8
reduce()
,reduceRight()
Algumas dessas coisas exigem que você especifique um número de versão do JavaScript para a execução (que quebrará no IE), mas algumas coisas como
[1,2,3].indexOf(2)
podem não parecer tão grandes, até que você tente executá-lo no IEfonte
javascript
e (a implementação específica)JScript
, não diferenças entreMozilla JavaScript(TM)
eJScript
. Pode ser melhor mostrar onde o IE se desvia do ES.As principais diferenças entre o JavaScript no IE e o JavaScript nos navegadores modernos (por exemplo, Firefox) podem ser atribuídas às mesmas razões por trás das diferenças no navegador cruzado CSS / (X) HTML. Antigamente não havia um padrão de fato; O IE / Netscape / Opera travou uma guerra de territórios, implementando a maioria das especificações, mas também omitindo algumas, bem como fazendo especificações proprietárias para obter vantagens umas sobre as outras. Eu poderia continuar, mas vamos pular para o lançamento do IE8: JavaScript foi evitado / desprezado por anos, e com a ascensão do FF e o desprezo do webcomm, o IE escolheu se concentrar principalmente no avanço de seu CSS a partir do IE6. E basicamente deixou o suporte DOM para trás. O suporte ao DOM do IE8 também pode ser o do IE6, que foi lançado em 2001 ... então o suporte ao DOM do IE está quase uma década atrás dos navegadores modernos. Se você tiver discrepâncias de JavaScript específicas para um mecanismo de layout, sua melhor aposta é atacá-lo da mesma forma que enfrentamos os problemas de CSS; Visando esse navegador. NÃO USE SNIFFING DE NAVEGADOR, use detecção de recursos para detectar seu navegador / seu nível de suporte DOM.
JScript não é a implementação de ECMAScript do IE; JScript foi a resposta do IE ao JavaScript da Netscape, ambos surgindo antes do ECMAScript.
No que diz respeito aos atributos de tipo no elemento de script, type = "text / javascript" é o padrão padrão (pelo menos em HTML5), então você nunca precisa de um atributo de tipo, a menos que seu script não seja JavaScript.
Quanto ao IE não suportar innerHTML ... innerHTML foi inventado pelo IE e ainda hoje NÃO é um padrão DOM. Outros navegadores o adotaram porque é útil, e é por isso que você pode usá-lo em vários navegadores. No que diz respeito à alteração dinâmica de tabelas, o MSDN diz "por causa da estrutura específica exigida pelas tabelas, o innerText e o innerHTML propriedades dos objetos table e tr são somente leitura." Não sei o quanto disso era verdade inicialmente, mas claramente os navegadores modernos descobriram enquanto lidavam com as complexidades do layout de tabelas.
Eu recomendo fortemente a leitura de PPK em JavaScript Jeremy Keith's DOM Scripting JavaScript de Douglas Crockford : The Good Parts e Christian Hellman's Beginning JavaScript with DOM Scripting e Ajax para obter um forte domínio sobre JavaScript.
No que diz respeito a Frameworks / Bibliotecas, se você ainda não tem um bom domínio de JavaScript, deve evitá-los. 2 anos atrás caí na armadilha do jQuery e, embora fosse capaz de realizar feitos magníficos, nunca aprendi absolutamente nada sobre como codificar JavaScript corretamente. Em retrospecto, o jQuery é um kit de ferramentas DOM incrível, mas minha falha em aprender fechamentos apropriados, herança prototípica, etc., não apenas atrasou meu conhecimento pessoal, mas meu trabalho começou a ter grandes impactos de desempenho porque eu não tinha ideia do que estava fazendo.
JavaScript é a linguagem do navegador; se você é um engenheiro do lado do cliente / front-end, é de extrema importância que você comande o JavaScript. Node.js está trazendo o JavaScript completo, vejo imensos avanços diários em seu desenvolvimento; O JavaScript do lado do servidor será um padrão em um futuro muito próximo. Estou mencionando isso para enfatizar ainda mais o quão importante o JavaScript é agora e será.
JavaScript vai fazer mais ondas do que Rails.
Bom script!
fonte
Alguns objetos nativos são somente leitura sem realmente parecerem ser (você pode escrever neles, mas não tem efeito). Por exemplo, um javascript avançado comum é baseado na extensão do
Element
objeto substituindo os métodos do sistema, digamos, alterando Element.prototype.appendChild () para fazer mais do que anexar um nó filho - digamos, inicializá-lo com os dados do pai. Isso falhará silenciosamente no IE6 - o método original será chamado em novos objetos em vez do novo.Alguns navegadores (não me lembro agora) consideram as novas linhas entre as tags HTML como nós de texto, enquanto outros não. Portanto, childNodes (n), nextSibling (), firstChild () e outros se comportarão de maneira muito diferente.
fonte
Vírgulas finais em matrizes e literais de objeto costumavam ser um problema, não verifiquei recentemente (ou seja, IE8):
Isso causaria algum código extra ao gerar tais estruturas do lado do servidor.
fonte
Acabei de encontrar um esta manhã, um colega de trabalho definiu a tag de script como:
<script type="application/javascript">
porque seu preenchimento automático de ide tinha isso antes de "text / javascript"Mas, acontece que o IE simplesmente ignora o script inteiro se você usar "application / javascript", você precisa usar "text / javascript"
fonte
<script>
Eu encontrei uma peculiaridade estranho outro dia com o Internet Explorer. Eu estava usando YUI e substituindo o conteúdo de um corpo de tabela () definindo o innerHTML
Isso funcionaria em todos os navegadores, EXCETO o IE. Finalmente descobri que não era possível substituir o innerHTML de uma tabela no IE. Tive que criar um nó usando YUI e, em seguida, anexar esse nó.
Essa foi divertida de descobrir!
fonte
<tbody>
etiquetas.Vírgulas extras e vírgulas ausentes costumavam ser um problema comum no IE, embora funcione bem no FF.
fonte
O IE é muito rígido quanto à ausência de ";" geralmente é isso.
fonte
Pelo que vale a pena, acabei de encontrar esse problema desagradável no <IE9
digamos que você tenha algum html como este:
e por algum motivo (eu tive um bom) você precisa recuperar todo o HTML na tabela antes do último TR de fechamento, você pode tentar algo assim:
<IE9 não retornará nada (-1) aqui porque a variável tableHtml contém todas as tags html com letras maiúsculas e lastIndexOf diferencia maiúsculas de minúsculas. Para contornar isso, tive que inserir um toLowerCase () antes de lastIndexOf.
fonte
O IE não é um navegador moderno e apenas segue o ECMAScript vagamente.
fonte
Você mencionou o jQuery, com o qual estou menos familiarizado, mas para referência geral e, especificamente, com Prototype, uma coisa a ser observada são palavras / nomes de métodos reservados no IE. Eu sei o que sempre me incomoda são coisas como:
someElement.appendChild(new Element('label',{ **for**: someInput.id }).update( someLabelText );
(new Element (tagName, propertyHash) é como os novos elementos são criados no Protitype). No IE,
for:
deve ser'for':
, porquefor
é uma palavra reservada. O que faz todo o sentido - mas o FireFox irá tolerar isso.Outro exemplo:
someElement.wrap('div').addClassName('someClass')
(o
wrap
método em Prototype envolve um elemento em outro) - No IE, em textareas,wrap
é uma propriedade eElement.wrap()
deve ser usado em vez da versão metodizadaEstes são dois exemplos que me vêm à mente com a minha experiência. Eles são baseados no protótipo, mas o problema principal não é: cuidado com quaisquer métodos / rótulos / identificadores que o IE considera palavras reservadas, mas o FireFox ou Safari toleram.
fonte
O fato é que o IE não suporta JavaScript ... Ele suporta sua própria implementação de ECMAScript: JScript ... que é um pouco diferente ...
fonte
Usar
console.log()
para enviar erros para o console de erro do Firefox fará com que seus scripts falhem no IE. Tenho que lembrar de tirá-los ao testar no IE.fonte