Ответ 1
Пожалуйста, не стесняйтесь обновлять этот список, если вы видите ошибки/упущения и т.д.
Примечание. IE9 устраняет многие из следующих проблем, поэтому многие из них относятся только к IE8 и ниже, а также к IE7 в режиме quirks. Например, IE9 поддерживает SVG, <canvas>
, <audio>
и <video>
изначально, однако вы должны включить режим соблюдения стандартов для них быть доступным.
Общие:
-
Проблемы с частично загруженными документами:. Хорошая идея добавить JavaScript в
window.onload
или подобное событие, поскольку IE не поддерживает много операций в частично загруженных документах. -
Различные атрибуты. В CSS это
elm.style.styleFloat
в IE vselm.style.cssFloat
в Firefox. В тегах<label>
к атрибутуfor
обращается с помощьюelm.htmlFor
в IE vselm.for
в Firefox. Обратите внимание, чтоfor
зарезервировано в IE, поэтомуelm['for']
, вероятно, является лучшей идеей остановить IE от создания исключения.
Основной язык JavaScript:
-
Доступ к символам в строках:
'string'[0]
не поддерживается в IE, поскольку он не соответствует исходным спецификациям JavaScript. Используйте'string'.charAt(0)
или'string'.split('')[0]
, отмечая, что доступ к элементам в массивах значительно быстрее, чем использованиеcharAt
со строками в IE (хотя при первом вызовеsplit
есть некоторые начальные накладные расходы). -
Запятые до конца объектов:.
{'foo': 'bar',}
в IE не разрешены.
Вопросы, связанные с элементом:
-
Получение
document
IFrame:- Firefox и IE8 +:
IFrame.contentDocument
(IE начал поддерживать этот с версии 8.) - IE:
IFrame.contentWindow.document
- (
IFrame.contentWindow
относится кwindow
в обоих браузерах.)
- Firefox и IE8 +:
-
Canvas: Версии IE до IE9 не поддерживают элемент
<canvas>
. IE поддерживает VML, который аналогичен технологии, и explorercanvas может предоставить оболочку на месте для элементов<canvas>
для многих операций. Имейте в виду, что IE8 в режиме соблюдения стандартов во много раз медленнее и имеет гораздо больше сбоев, чем в режиме quirks при использовании VML. -
SVG: IE9 поддерживает SVG изначально. IE6-8 может поддерживать SVG, но только с внешние плагины только с некоторыми из этих плагинов, поддерживающих JavaScript-манипуляцию.
-
<audio>
и<video>
: поддерживаются только в IE9. -
Динамическое создание переключателей: У IE < 8 есть ошибка, которая делает переключатели, созданные с помощью
document.createElement
неконтролируемой. См. Также Как вы динамически создаете переключатель в Javascript, который работает во всех браузерах?, чтобы обойти это. -
Встроенный JavaScript в тегах
/li ><a href>
иonbeforeunload
конфликты в IE: Если встроенный JavaScript в тегеhref
тегаa
(например,<a href="javascript: doStuff()">
) IE всегда будет отображать сообщение, возвращенное изonbeforeunload
, если обработчикonbeforeunload
не будет удален заранее. См. Также Запросить подтверждение при закрытии вкладки. -
<script>
различия между тегами:onsuccess
иonerror
не поддерживаются в IE и заменяются IE-специфическимonreadystatechange
, который запускается независимо от того, загрузка прошла успешно или не удалась. См. Также JavaScript Madness для получения дополнительной информации.
Размер элемента/положение/прокрутка и положение мыши:
-
Получение размера элемента/позиции: ширина/высота элементов иногда
elm.style.pixelHeight/Width
в IE, а неelm.offsetHeight/Width
, но ни одна из них не является надежной в IE, особенно в режиме quirks, и иногда один дает лучший результат, чем другой.elm.offsetTop
иelm.offsetLeft
часто сообщаются неправильно, что приводит к неверному определению позиций элементов, поэтому во многих случаях во всплывающих панелях и т.д. несколько пикселей.Также обратите внимание, что если элемент (или родительский элемент) имеет
display
ofnone
, тогда IE будет вызывать исключение при доступе к атрибутам size/position, а не возвращать0
, как это делает Firefox. -
Получить размер экрана (получение области видимости экрана):
- Firefox:
window.innerWidth/innerHeight
- Режим стандартов IE:
document.documentElement.clientWidth/clientHeight
- Режим IE quirks:
document.body.clientWidth/clientHeight
- Firefox:
-
Позиция прокрутки документа/позиция мыши. Этот файл на самом деле не определен w3c, поэтому он нестандартен даже в Firefox. Чтобы найти
scrollLeft
/scrollTop
document
:- Firefox и IE в режиме quirks:
document.body.scrollLeft/scrollTop
- IE в стандартном режиме:
document.documentElement.scrollLeft/scrollTop
-
ПРИМЕЧАНИЕ. Некоторые другие браузеры также используют
pageXOffset
/pageYOffset
.function getDocScrollPos() { var x = document.body.scrollLeft || document.documentElement.scrollLeft || window.pageXOffset || 0, y = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset || 0; return [x, y]; };
Чтобы получить позицию курсора мыши, события
evt.clientX
иevt.clientY
вmousemove
будут давать позицию относительно документа без добавления положения прокрутки, чтобы была включена предыдущая функция:var mousepos = [0, 0]; document.onmousemove = function(evt) { evt = evt || window.event; if (typeof evt.pageX != 'undefined') { // Firefox support mousepos = [evt.pageX, evt.pageY]; } else { // IE support var scrollpos = getDocScrollPos(); mousepos = [evt.clientX+scrollpos[0], evt.clientY+scrollpos[1]]; }; };
- Firefox и IE в режиме quirks:
Выбор/диапазонов:
-
<textarea>
и<input>
выборы:selectionStart
иselectionEnd
не реализованы в IE, и вместо этого на их месте имеется собственная система "диапазонов", см. также Позиция Caret в textarea, в символах с начала. -
Получение текущего текста в документе:
- Firefox:
window.getSelection().toString()
- IE:
document.selection.createRange().text
- Firefox:
Получение элементов по ID:
-
document.getElementById
также может ссылаться на атрибутname
в формах (в зависимости от того, что определено вначале в документе), поэтому лучше не иметь разных элементов, которые имеют те жеname
иid
. Это относится ко времени, когдаid
не был стандартом w3c.document.all
(проприетарное свойство, специфичное для IE) значительно быстрее, чемdocument.getElementById
, но у него есть другие проблемы, так как он всегда выделяет приоритетname
доid
. Я лично использую этот код, возвращаясь с дополнительными проверками, чтобы быть уверенным:function getById(id) { var e; if (document.all) { e = document.all[id]; if (e && e.tagName && e.id === id) { return e; }; }; e = document.getElementById(id); if (e && e.id === id) { return e; } else if (!e) { return null; } else { throw 'Element found by "name" instead of "id": ' + id; }; };
Проблемы только с чтением innerHTML:
-
IE не поддерживает установку innerHTML из
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
иtr
. Здесь функция, которая работает вокруг этого для связанных с таблицами элементов:function setHTML(elm, html) { // Try innerHTML first try { elm.innerHTML = html; } catch (exc) { function getElm(html) { // Create a new element and return the first child var e = document.createElement('div'); e.innerHTML = html; return e.firstChild; }; function replace(elms) { // Remove the old elements from 'elm' while (elm.children.length) { elm.removeChild(elm.firstChild); } // Add the new elements from 'elms' to 'elm' for (var x=0; x<elms.children.length; x++) { elm.appendChild(elms.children[x]); }; }; // IE 6-8 don't support setting innerHTML for // TABLE, TBODY, TFOOT, THEAD, and TR directly var tn = elm.tagName.toLowerCase(); if (tn === 'table') { replace(getElm('<table>' + html + '</table>')); } else if (['tbody', 'tfoot', 'thead'].indexOf(tn) != -1) { replace(getElm('<table><tbody>' + html + '</tbody></table>').firstChild); } else if (tn === 'tr') { replace(getElm('<table><tbody><tr>' + html + '</tr></tbody></table>').firstChild.firstChild); } else { throw exc; }; }; };
Также обратите внимание, что IE требует добавления
<tbody>
в<table>
перед добавлением<tr>
к этому элементу<tbody>
при создании с помощьюdocument.createElement
, например:var table = document.createElement('table'); var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); var td = document.createElement('td'); table.appendChild(tbody); tbody.appendChild(tr); tr.appendChild(td); // and so on
Различия в событиях:
-
Получение переменной
event
: DOM-события не передаются в функции IE и доступны какwindow.event
. Одним из распространенных способов получения события является использование, например,elm.onmouseover = function(evt) {evt = evt||window.event}
который по умолчанию равенwindow.event
, еслиevt
равен undefined. -
Различия в ключевых событиях кода: Коды ключевых событий сильно различаются, но если вы посмотрите на Quirksmode или JavaScript Madness, это вряд ли специфично для IE, Safari и Opera отличаются друг от друга.
-
Различия в событиях мыши: атрибут
button
в IE - это бит-флаг, который позволяет сразу несколько кнопок мыши:- Слева: 1 (
var isLeft = evt.button & 1
) - Вправо: 2 (
var isRight = evt.button & 2
) -
Центр: 4 (
var isCenter = evt.button & 4
)Модель W3C (поддерживается Firefox) менее гибкая, чем модель IE, причем только одна кнопка разрешена сразу с левой стороны как
0
, прямо как2
и центром как1
. Обратите внимание, что, как упоминает Peter-Paul Koch , это очень противоречиво, поскольку0
обычно означает "нет кнопки".offsetX
иoffsetY
являются проблематичными, и, вероятно, лучше избегать их в IE. Более надежный способ получитьoffsetX
иoffsetY
в IE будет получить позицию относительно позиционированного элемента и вычесть его изclientX
иclientY
.Также обратите внимание, что в IE для двойного щелчка в событии
click
вам необходимо зарегистрировать событиеclick
иdblclick
для функции. Firefox срабатываетclick
, а такжеdblclick
при двойном щелчке, поэтому для определения того же поведения требуется определение, специфичное для IE.
- Слева: 1 (
-
Различия в модели обработки событий:И проприетарная модель IE, и модель Firefox поддерживают обработку событий снизу вверх, например. если есть события в обоих элементах
<div><span></span></div>
, тогда события будут запускаться вspan
, затем вdiv
, а не в порядке, который они связаны, если традиционный, например,elm.onclick = function(evt) {}
.События "Capture" обычно поддерживаются только в Firefox и т.д., Которые вызывают события
div
иspan
в порядке сверху вниз. IE имеетelm.setCapture()
иelm.releaseCapture()
для перенаправления событий мыши из документа в элемент (elm
в этом случае) перед обработкой других событий, но у них есть ряд характеристик производительности и других проблем, поэтому, вероятно, этого следует избегать.-
Firefox:
Прикрепить:
elm.addEventListener(type, listener, useCapture [true/false])
Отсоединить:elm.removeEventListener(type, listener, useCapture)
(type
является, например,'mouseover'
безon
) -
IE: В IE может быть добавлено только одно событие определенного типа в элементе - исключение возникает, если добавлено более одного события того же типа. Также обратите внимание, что
this
относится кwindow
, а не к связанному элементу в функциях событий (поэтому менее полезно):Прикрепить:
elm.attachEvent(sEvent, fpNotify)
Отсоединить:elm.detachEvent(sEvent, fpNotify)
(sEvent
является, например,'onmouseover'
)
-
-
Различия атрибутов событий:
-
Остановить события от обработки другими функциями прослушивания:
Firefox:
evt.stopPropagation()
IE:evt.cancelBubble = true
-
Стоп, например. ключевые события от вставки символов или остановки флажков от проверки:
Firefox:
evt.preventDefault()
IE:evt.returnValue = false
Примечание.. Только возвратfalse
вkeydown
,keypress
,mousedown
,mouseup
,click
иreset
также предотвратит по умолчанию. -
Получить элемент, вызвавший событие:
Firefox:
evt.target
IE:evt.srcElement
-
Получение элемента курсором мыши от:
evt.fromElement
в IEevt.target
в Firefox, если в событииonmouseout
, в противном случаеevt.relatedTarget
-
Получение элемента, на который перемещается указатель мыши:
evt.toElement
в IEevt.relatedTarget
в Firefox, если в событииonmouseout
, в противном случаеevt.target
-
Примечание.
evt.currentTarget
(элемент, к которому привязано событие) не имеет эквивалента в IE.
-