J'ai développé des pages améliorées javascript qui fonctionnent bien sur Firefox et Safari récents. J'ai manqué de vérifier dans Internet Explorer, et maintenant je trouve que les pages ne fonctionnent pas sur IE 6 et 7 (jusqu'à présent). Les scripts ne sont pas exécutés d'une manière ou d'une autre, les pages s'affichent comme si javascript n'était pas là, bien que certains javascript soient exécutés. J'utilise mes propres bibliothèques avec manipulation dom, de YUI 2 j'utilise YUI-Loader et XML-Http-Request, et sur une page j'utilise "psupload", qui dépend de JQuery.
J'installe Microsoft Script Editor à partir d'Office XP et je vais maintenant déboguer. J'écrirai également des tests spécifiques maintenant.
Quels sont les points de défaillance typiques d'IE? Dans quelle direction je peux garder les yeux ouverts.
J'ai trouvé cette page, qui montre quelques différences. visite: Quirksmode
Pouvez-vous, d'après votre expérience, nommer des éléments typiques que je devrais rechercher en premier?
Je poserai également plus de questions ici pour des tâches spécifiques plus tard, mais pour l'instant, je suis intéressé par votre expérience des raisons pour lesquelles IE échoue généralement sur les scripts qui fonctionnent bien dans Firefox
Edit: Merci pour toutes ces bonnes réponses!
En attendant, j'ai adapté l'ensemble du code pour qu'il fonctionne également avec Internet Explorer. J'ai intégré jQuery et construit mes propres classes dessus maintenant. C'était mon erreur fondamentale, de ne pas avoir construit tout mon contenu sur jQuery depuis le début. Maintenant j'ai.
JSLint m'a également beaucoup aidé.
Et bon nombre des problèmes uniques des différentes réponses ont aidé.
la source
Réponses:
N'hésitez pas à mettre à jour cette liste si vous voyez des erreurs / omissions, etc.
Remarque: IE9 corrige bon nombre des problèmes suivants, donc une grande partie de cela ne s'applique qu'à IE8 et aux versions antérieures et dans une certaine mesure à IE9 en mode bizarreries. Par exemple, IE9 supporte SVG,
<canvas>
,<audio>
et en mode<video>
natif, mais vous devez activer le mode de conformité aux normes pour qu'elles soient disponibles.Général:
Problèmes avec les documents partiellement chargés: c'est une bonne idée d'ajouter votre JavaScript dans un
window.onload
événement ou un événement similaire, car IE ne prend pas en charge de nombreuses opérations dans les documents partiellement chargés.Attributs différents : en CSS, c'est
elm.style.styleFloat
dans IE par rapportelm.style.cssFloat
à Firefox. Dans les<label>
balises, l'for
attribut est accessible avecelm.htmlFor
dans IE vselm.for
dans Firefox. Notez que celafor
est réservé dans IE,elm['for']
c'est donc probablement une meilleure idée pour empêcher IE de déclencher une exception.Langage JavaScript de base:
Accéder aux caractères dans les chaînes :
'string'[0]
n'est pas pris en charge dans IE car il ne figure pas dans les spécifications JavaScript d'origine. Utilisez'string'.charAt(0)
ou'string'.split('')[0]
notez que l'accès aux éléments dans les tableaux est beaucoup plus rapide que l'utilisationcharAt
avec des chaînes dans IE (bien qu'il y ait une surcharge initiale lors dusplit
premier appel.)Les virgules avant la fin des objets: par exemple,
{'foo': 'bar',}
ne sont pas autorisées dans IE.Problèmes spécifiques aux éléments:
Obtenir le
document
d'un IFrame :IFrame.contentDocument
(IE a commencé à prendre en charge cela à partir de la version 8. )IFrame.contentWindow.document
IFrame.contentWindow
fait référence auwindow
dans les deux navigateurs.)Canvas: les versions d'IE antérieures à IE9 ne prennent pas en charge l'
<canvas>
élément. Cependant, IE prend en charge VML qui est une technologie similaire, et explorercanvas peut fournir un wrapper sur place pour les<canvas>
éléments de nombreuses opérations. Sachez que IE8 en mode de conformité aux normes est plusieurs fois plus lent et comporte beaucoup plus de problèmes qu'en mode bizarreries lors de l'utilisation de VML.SVG: IE9 prend en charge SVG nativement. IE6-8 peut prendre en charge SVG, mais uniquement avec des plugins externes avec seulement certains de ces plugins prenant en charge la manipulation JavaScript.
<audio>
et<video>
: ne sont pris en charge que dans IE9.Création dynamique de boutons radio: IE <8 a un bogue qui rend les boutons radio créés avec
document.createElement
uncheckable. Voir aussi Comment créer dynamiquement un bouton radio en Javascript qui fonctionne dans tous les navigateurs? pour un moyen de contourner cela.JavaScript incorporé dans les
<a href>
balises etonbeforeunload
conflits dans IE: S'il y a du JavaScript intégré dans lahref
partie d'unea
balise (par exemple,<a href="javascript: doStuff()">
IE affichera toujours le message renvoyé àonbeforeunload
moins que leonbeforeunload
gestionnaire ne soit supprimé au préalable. Voir aussi Demander confirmation lors de la fermeture d'un onglet .<script>
différences d'événement de balise:onsuccess
etonerror
ne sont pas pris en charge dans IE et sont remplacés par un IE spécifiqueonreadystatechange
qui est déclenché, que le téléchargement ait réussi ou échoué. Voir aussi JavaScript Madness pour plus d'informations.Taille / position / défilement des éléments et position de la souris:
Obtenir la taille / la position de l'élément : la largeur / la hauteur des éléments est parfois
elm.style.pixelHeight/Width
dans IE plutôt queelm.offsetHeight/Width
, mais ni l'un ni l'autre n'est fiable dans IE, en particulier en mode bizarreries, et parfois l'un donne un meilleur résultat que l'autre.elm.offsetTop
etelm.offsetLeft
sont souvent signalés de manière incorrecte, ce qui conduit à trouver des positions d'éléments incorrectes, c'est pourquoi les éléments contextuels, etc., sont à quelques pixels dans de nombreux cas.Notez également que si un élément (ou un parent de l'élément) a un
display
de,none
alors IE lèvera une exception lors de l'accès aux attributs de taille / position plutôt que de retourner0
comme le fait Firefox.Obtenez la taille de l'écran (Obtention de la zone visible de l'écran):
window.innerWidth/innerHeight
document.documentElement.clientWidth/clientHeight
document.body.clientWidth/clientHeight
Position de défilement du document / position de la souris : celle-ci n'est en fait pas définie par le w3c et n'est donc pas standard même dans Firefox. Pour trouver le
scrollLeft
/scrollTop
dudocument
:document.body.scrollLeft/scrollTop
document.documentElement.scrollLeft/scrollTop
REMARQUE: certains autres navigateurs utilisent également
pageXOffset
/pageYOffset
.Afin d'obtenir la position du curseur de la souris,
evt.clientX
etevt.clientY
dans lesmousemove
événements donnera la position relative au document sans ajouter la position de défilement donc la fonction précédente devra être incorporée:Sélections / plages:
<textarea>
et<input>
sélections :selectionStart
etselectionEnd
ne sont pas implémentés dans IE, et il y a un système propriétaire de "gammes" à sa place, voir aussi Position du curseur dans textarea, en caractères dès le début .Obtenir le texte actuellement sélectionné dans le document:
window.getSelection().toString()
document.selection.createRange().text
Obtenir des éléments par ID:
document.getElementById
peut également faire référence à l'name
attribut dans les formulaires (en fonction de celui qui est défini en premier dans le document), il est donc préférable de ne pas avoir différents éléments qui ont le mêmename
etid
. Cela remonte à l'époque où ceid
n'était pas un standard du W3C.document.all
( une propriété propre à IE ) est nettement plus rapide quedocument.getElementById
, mais elle présente d'autres problèmes car elle priorise toujoursname
avantid
. J'utilise personnellement ce code, en retombant avec des vérifications supplémentaires juste pour être sûr:Problèmes avec la lecture seule innerHTML:
IE ne prend pas en charge le réglage de la innerHTML de
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
, et lestr
éléments. Voici une fonction qui fonctionne autour de cela pour les éléments liés aux tables:Notez également que IE nécessite l'ajout de a
<tbody>
à a<table>
avant d'ajouter<tr>
s à cet<tbody>
élément lors de la création en utilisantdocument.createElement
, par exemple:Différences d'événements:
Obtention de la
event
variable: les événements DOM ne sont pas passés aux fonctions dans IE et sont accessibles en tant quewindow.event
. Une manière courante d'obtenir l'événement est d'utiliser par exemple la valeur parelm.onmouseover = function(evt) {evt = evt||window.event}
défaut
window.event
ifevt
n'est pas définie.Différences entre les codes d'événements clés : les codes d'événements clés varient énormément, bien que si vous regardez Quirksmode ou JavaScript Madness , ce n'est guère spécifique à IE, Safari et Opera sont à nouveau différents.
Différences d'événements de souris: l'
button
attribut dans IE est un bit-flag qui autorise plusieurs boutons de souris à la fois:var isLeft = evt.button & 1
)var isRight = evt.button & 2
)Centre: 4 (
var isCenter = evt.button & 4
)Le modèle W3C (pris en charge par Firefox) est moins flexible que le modèle IE, avec un seul bouton autorisé à la fois avec la gauche comme
0
, la droite comme2
et le centre comme1
. Notez que, comme le mentionne Peter-Paul Koch , cela est très contre-intuitif, car cela0
signifie généralement «pas de bouton».offsetX
etoffsetY
sont problématiques et il est probablement préférable de les éviter dans IE. Un moyen plus fiable d'obtenir leoffsetX
etoffsetY
dans IE serait d' obtenir la position de l'élément relativement positionné et de le soustraire declientX
etclientY
.Notez également que dans IE, pour obtenir un double-clic dans un
click
événement, vous devez enregistrer à la fois un événementclick
etdblclick
une fonction. Firefox se déclencheclick
ainsi quedblclick
lors d'un double-clic, donc une détection spécifique à IE est nécessaire pour avoir le même comportement.Les différences dans le modèle de gestion des événements: Tant le modèle IE propriétaire et le traitement de soutien du modèle Firefox des événements dès le départ en bas, par exemple , s'il y a des événements dans les deux éléments
<div><span></span></div>
puis événements déclenchent enspan
alors lediv
lieu de l'ordre qu'ils sont lié si un exemple traditionnel aelm.onclick = function(evt) {}
été utilisé.Les événements "Capture" ne sont généralement pris en charge que dans Firefox, etc., ce qui déclenchera
div
ensuite lesspan
événements dans un ordre descendant. IE aelm.setCapture()
etelm.releaseCapture()
pour rediriger les événements de souris du document vers l'élément (elm
dans ce cas) avant de traiter d'autres événements, mais ils ont un certain nombre de problèmes de performances et d'autres donc devraient probablement être évités.Firefox:
Attach :
elm.addEventListener(type, listener, useCapture [true/false])
Detach :
elm.removeEventListener(type, listener, useCapture)
(
type
est par exemple'mouseover'
sans leon
)IE: Un seul événement d'un type donné sur un élément peut être ajouté dans IE - une exception est déclenchée si plus d'un événement du même type est ajouté. Notez également que le
this
fait référence àwindow
plutôt qu'à l'élément lié dans les fonctions d'événement (c'est donc moins utile):Joindre :
elm.attachEvent(sEvent, fpNotify)
Détacher :
elm.detachEvent(sEvent, fpNotify)
(
sEvent
est par exemple'onmouseover'
)Différences d'attributs d'événement:
Arrêtez le traitement des événements par toute autre fonction d'écoute :
Firefox:
evt.stopPropagation()
IE:
evt.cancelBubble = true
Arrêtez, par exemple, les événements clés d'insérer des caractères ou d'empêcher les cases à cocher d'être cochées:
Firefox:
evt.preventDefault()
IE:
evt.returnValue = false
Note: Je viens de revenir
false
enkeydown
,keypress
,mousedown
,mouseup
,click
etreset
empêchera également défaut.Récupérez l'élément qui a déclenché l'événement:
Firefox:
evt.target
IE:
evt.srcElement
Obtention de l'élément dont le curseur de la souris s'est éloigné:
evt.fromElement
dans IE se trouveevt.target
dans Firefox si dans unonmouseout
événement, sinonevt.relatedTarget
Obtention de l'élément vers lequel le curseur de la souris a été déplacé:
evt.toElement
dans IE estevt.relatedTarget
dans Firefox si dans unonmouseout
événement, sinonevt.target
Remarque:
evt.currentTarget
(l'élément auquel l'événement était lié) n'a pas d'équivalent dans IE.la source
Vérifiez également les virgules telles que celles-ci ou similaires le cas échéant dans votre code
la dernière virgule (valeur suivante2) sera tolérée par Firefox, mais pas IE
la source
Si vous vous en tenez à utiliser jQuery ou YUI lorsque votre message est balisé, vous devriez avoir des différences minimes entre les navigateurs ... c'est à cela que servent les frameworks, pour prendre en charge ces différences entre navigateurs pour vous.
Pour un exemple, regardez la page de traversée du DOM quirksmode , selon elle, IE ne prend pas en charge la plupart des choses ... alors que c'est vrai, les frameworks le font, par exemple IE ne prend pas en charge
elem.childElementCount
, mais dans jQuery:$(elem).children().size()
fonctionne pour obtenir cette valeur, dans chaque navigateur. Vous constaterez qu'il y a quelque chose dans la bibliothèque pour gérer 99% des cas non pris en charge dans les navigateurs, au moins avec un script ... avec CSS, vous devrez peut-être passer aux plugins pour la bibliothèque, un exemple courant est d'obtenir des coins arrondis travaillant dans IE ... car il n'a pas de support CSS pour un tel.Si toutefois vous commencez à faire des choses directement, comme
document.XXX(thing)
, alors vous n'êtes pas dans la bibliothèque, vous faites du javascript directement (tout est javascript, mais vous comprenez :), et cela peut ou non causer des problèmes, selon la façon dont ivre l'équipe IE était lors de la mise en œuvre de cette fonction particulière.Avec IE, vous êtes plus susceptible d'échouer en termes de style que les problèmes javascript bruts, les animations à quelques pixels de distance et ce genre de choses, bien plus encore dans IE6 bien sûr.
la source
getElementbyID correspondra également à l'attribut name dans IE, mais pas aux autres navigateurs, et IE sélectionnera celui qu'il trouve en premier.
exemple:
la source
Il y a beaucoup de choses, mais un piège dans lequel je tombais était que de nombreux navigateurs acceptaient JSON sans les noms entre guillemets, contrairement à ie6 et ie7.
Edit : Pour clarifier, ce n'est un problème que lorsque JSON réel est requis, par opposition à un littéral d'objet. JSON est un sous-ensemble de la syntaxe littérale d'objet et est conçu comme un format d'échange de données (comme XML), c'est pourquoi il est conçu pour être plus sélectif.
la source
Prise en charge différente de JavaScript
IE ne prend pas en charge (la plupart) les extensions ajoutées à JavaScript depuis la version 1.5.
Nouveau dans la 1.6
indexOf()
,lastIndexOf()
,every()
,filter()
,forEach()
,map()
,some()
for each ... in
- itère les valeurs au lieu des noms de propriété.Nouveau dans la 1.7
[a,b] = [1,2]
let
etconst
déclarationsNouveau dans la 1.8
reduce()
,reduceRight()
Certaines de ces choses vous obligent à spécifier un numéro de version de JavaScript sous lequel s'exécuter (qui se cassera sous IE), mais certaines choses comme
[1,2,3].indexOf(2)
peuvent ne pas sembler si importantes, jusqu'à ce que vous essayiez de l'exécuter dans IEla source
javascript
et (l'implémentation spécifique)JScript
, pas les différences entreMozilla JavaScript(TM)
etJScript
. Il serait peut-être préférable de montrer où IE s'écarte d'ES.Les différences majeures entre JavaScript dans IE et JavaScript dans les navigateurs modernes (ex, Firefox) peuvent être attribuées aux mêmes raisons derrière les différences dans les navigateurs croisés CSS / (X) HTML. À l'époque, il n'y avait pas de norme de facto; IE / Netscape / Opera ont mené une guerre de territoire, implémentant la plupart des spécifications, mais également en omettant certaines et en créant des spécifications propriétaires pour gagner des avantages les uns sur les autres. Je pourrais continuer longtemps, mais passons à la sortie d'IE8: JavaScript a été évité / méprisé pendant des années, et avec la montée en puissance de FF et le mépris de webcomm, IE a choisi de se concentrer principalement sur l'avancement de leur CSS à partir d'IE6. Et essentiellement laissé le support DOM derrière. Le support DOM d'IE8 pourrait tout aussi bien être celui d'IE6, qui a été déployé en 2001 ... donc le support DOM d'IE8 a presque dix ans de retard sur les navigateurs modernes. Si vous rencontrez des divergences JavaScript spécifiques à un moteur de mise en page, le mieux est de l'attaquer de la même manière que nous avons résolu les problèmes CSS; Cibler ce navigateur. N'UTILISEZ PAS LE BROWSER SNIFFING, utilisez la détection des fonctionnalités pour détecter votre navigateur / son niveau de support DOM.
JScript n'est pas la propre implémentation d'ECMAScript par IE; JScript était la réponse d'IE au JavaScript de Netscape, tous deux nés avant ECMAScript.
En ce qui concerne les attributs de type sur l'élément de script, type = "text / javascript" est la norme par défaut (au moins en HTML5), vous n'avez donc jamais besoin d'un attribut de type à moins que votre script ne soit pas JavaScript.
En ce qui concerne IE ne supportant pas innerHTML ... innerHTML a été inventé par IE et n'est pas encore aujourd'hui un standard DOM. D'autres navigateurs l'ont adopté car il est utile, c'est pourquoi vous pouvez l'utiliser sur plusieurs navigateurs. En changeant dynamiquement jusqu'à tableaux, MSDN dit « en raison de la structure spécifique requise par les tables, les innerText et innerHTML propriétés des objets de table et tr sont en lecture seule. » Je ne sais pas à quel point c'était vrai au départ, mais il est clair que les navigateurs modernes l'ont compris tout en faisant face aux complexités de la mise en page des tableaux.
Je recommande vivement de lire PPK sur JavaScript Scripting DOM de Jeremy Keith JavaScript: The Good Parts de Douglas Crockford et Beginning JavaScript with DOM Scripting and Ajax de Christian Hellman pour bien comprendre JavaScript.
En ce qui concerne les cadres / bibliothèques, si vous ne maîtrisez pas encore très bien JavaScript, vous devez les éviter. Il y a 2 ans, je suis tombé dans le piège de jQuery, et bien que j'aie pu réaliser de magnifiques exploits, je n'ai jamais rien appris sur le codage correct de JavaScript. Avec le recul, jQuery est une boîte à outils DOM géniale, mais mon échec à apprendre les fermetures appropriées, l'héritage prototypique, etc.
JavaScript est la langue du navigateur; si vous êtes ingénieur côté client / front-end, il est de la plus haute importance que vous commandiez JavaScript. Node.js apporte la pleine inclinaison de JavaScript, je vois d'immenses progrès réalisés quotidiennement dans son développement; Le JavaScript côté serveur deviendra une norme dans un très proche avenir. Je mentionne cela pour souligner davantage à quel point JavaScript est et sera important.
JavaScript va faire plus de vagues que Rails.
Joyeux script!
la source
Certains objets natifs sont en lecture seule sans en avoir vraiment l'air (vous pouvez y écrire mais cela n'a aucun effet). Par exemple, un javascript avancé commun est basé sur l'extension de l'
Element
objet en remplaçant les méthodes système, par exemple, en modifiant Element.prototype.appendChild () pour faire plus que l'ajout d'un nœud enfant - disons, l'initialiser avec les données du parent. Cela échouera silencieusement sur IE6 - la méthode d'origine sera appelée sur les nouveaux objets au lieu du nouveau.Certains navigateurs (je ne me souviens plus lequel maintenant) considèrent les nouvelles lignes entre les balises HTML comme des nœuds de texte, tandis que d'autres ne le font pas. Ainsi, childNodes (n), nextSibling (), firstChild () et autres se comporteront très différemment.
la source
Les virgules de fin dans les tableaux et les littéraux d'objet étaient un problème, n'ont pas été vérifiées récemment (ce qui signifie IE8):
Cela entraînerait du code supplémentaire lors de la génération de telles structures côté serveur.
la source
Je viens d'en trouver un ce matin, un collègue a défini la balise de script comme suit:
<script type="application/javascript">
parce que son ide autocomplete avait cela avant "text / javascript"Mais, il s'avère que IE ignore tout le script si vous utilisez "application / javascript", vous devez utiliser "text / javascript"
la source
<script>
J'ai trouvé une bizarrerie l'autre jour avec Internet Explorer. J'utilisais YUI et remplaçais le contenu d'un corps de table () en définissant le innerHTML
Cela fonctionnerait dans tous les navigateurs SAUF IE. J'ai finalement découvert que vous ne pouviez pas remplacer le innerHTML d'une table dans IE. J'ai dû créer un nœud en utilisant YUI, puis ajouter ce nœud.
C'était amusant à comprendre!
la source
<tbody>
étiquettes.Les virgules supplémentaires et les virgules manquantes étaient un problème habituel sur IE alors que cela fonctionne correctement sur FF.
la source
IE est très stricte sur le fait de manquer ";" il en est généralement de même.
la source
Pour ce que ça vaut, je viens de tomber sur ce problème désagréable dans <IE9
disons que vous avez du code HTML comme celui-ci:
et pour une raison quelconque (j'en ai eu une bonne), vous devez récupérer tout le HTML du tableau avant le dernier TR de fermeture, vous pouvez essayer quelque chose comme ceci:
<IE9 ne renvoie rien (-1) ici car la variable tableHtml contient toutes les balises html en majuscules et lastIndexOf est sensible à la casse. Pour contourner cela, j'ai dû lancer un toLowerCase () avant lastIndexOf.
la source
IE n'est pas un navigateur moderne et ne suit ECMAScript que vaguement.
la source
Vous avez mentionné jQuery avec lequel je suis moins familier, mais pour référence générale, et en particulier avec Prototype, une chose à surveiller est les mots / noms de méthodes réservés dans IE. Je sais ce qui m'attire souvent, ce sont des choses comme:
someElement.appendChild(new Element('label',{ **for**: someInput.id }).update( someLabelText );
(new Element (tagName, propertyHash) est la façon dont les nouveaux éléments sont créés dans Protitype). Dans IE,
for:
doit être'for':
, carfor
est un mot réservé. Ce qui est tout à fait logique - mais FireFox le tolérera.Un autre exemple:
someElement.wrap('div').addClassName('someClass')
(la
wrap
méthode de Prototype enveloppe un élément dans un autre) - Dans IE, sur textareas,wrap
est une propriété, etElement.wrap()
doit être utilisée à la place de la version méthodiséeCe sont deux exemples qui me viennent à l'esprit de mon expérience. Ils sont basés sur un prototype, mais le problème principal n'est pas: faites attention aux méthodes / étiquettes / identificateurs que IE considère comme des mots réservés mais que FireFox ou Safari les toléreront.
la source
Le fait est que IE ne prend pas en charge JavaScript ... Il prend en charge sa propre implémentation d'ECMAScript: JScript ... ce qui est un peu différent ...
la source
En utilisant
console.log()
pour afficher les erreurs sur la console d'erreur Firefox entraînera l'échec de vos scripts dans IE. N'oubliez pas de les retirer lorsque vous testez dans IE.la source