JavaScript: как правильно курить IE10, или проблемы миграции

Авторское отступление: Не закидывайте камнями те, кому выпало писать под разные браузеры!
В моей работе из-за использования ActiveX-компонентов сейчас поддерживается только IE. Поэтому дальнейшее изложение касается только различных версий IE.

IE10 — это особый браузер. Многое из того, что было верно для предыдущий версий IE, перестало работать.
Рассматриваются только ошибки JavaScript, возникшие при миграции legacy-кода. Различие в CSS выходит за рамки данной статьи.

Итак, ниже представлен перечень типичных ошибок в IE10, возникающих при переходе со старых версий IE.

1. Крестик для очистки поля

В IE10 при вводе в текстовое поле появляется крестик, предназначенный для очистки поля (кроме маленьких полей).

В случае, когда используется онлайн-валидация полей форм, а также любые другие изменения в зависимости от значения поля, это сулит некоторое количество проблем. Они связаны с тем, что очистка поля при нажатии крестика — это событие input. При этом события change (а также keydown, keypress и keyup), не происходит. Точнее, происходит только при потере фокуса. Со всеми вытекающими, т.к. это не является ожидаемым поведением для пользователя (с точки зрения привычной нам обработки событий).

При этом скрыть этот крестик с использованием CSS можно только в режиме документов IE10:

.someinput::-ms-clear {
    display: none;
    width: 0;
    height: 0;
}

 

В режиме совместимости эта возможность отсутствует. Остается ловить mousedown/mouseup и проверять, не изменилось ли значение поля после клика. Довольно печально (хотя это и работает).

2. Нет XPath?

В IE10 свойство responseXml объекта ActiveXObject(‘MSXML2.XMLHTTP’) теперь возвращает не IXMLDocument, а Document, у которого нет методов selectSingleNode и selectNodes, работающих с XPath (см. источник).

Выход состоит в задании responseType:

if (window.XMLHttpRequest) {
    try {
        ajaxXHR.responseType = "msxml-document";
    } catch (e) {
        // ignore
    }
}

 

При этом надо не забыть, что возвращается документ версии 3.0, тогда как в старых версиях возвращался документ версии 2.0. Документы разных версий не совместимы между собой.

3. В DOM-модель нельзя добавлять custom-свойства

Вместо них используем custom-атрибуты (getAttribute()/setAttribute()). При этом при добавлении custom-атрибута к тегу он становится доступным через getAttribute().

Необходимо помнить, что custom-атрибуты должны быть строками, а не объектами. В IE10 объекты, переданные в setAttribute(), конвертируется в строку.

4. event.returnValue не поддерживаются

Вместо этого используем preventDefault:

if (event.preventDefault) {
  event.preventDefault();
} else {
  event.returnValue = false;
}

 


Если кто-нибудь встречался с другими особенностями IE10 при мигрировании JavaScript-кода — буду рад добавить к статье, пишите в комментариях.