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-кода — буду рад добавить к статье, пишите в комментариях.
    Поделиться публикацией
    Комментарии 21
      +7
      Особенно радует статья в свете скорого выхода IE11
        0
        Увы, я на некоторое время «выпал» из контекста.
        Только сейчас добрался оформить в виде статьи.
          0
          Очень полезная инфа про «XPath выпилили», в 11ом его тоже нет оказывается, теперь из-за этих нехороших людей из Бангалоредмонда можно не ждать Selenium драйвер для IE10 IE11
        +6
        Иногда кажется, что они делают это специально.
          +12
          Конечно специально. Их цель — привести браузер к стандартам.
          +3
          Для инпута с типом password IE10 добавляет свой значок для показа\скрытия символов. Убирается аналогично крестику для очистки поля:

          sel::-ms-reveal {
              display: none;
          }
          

          где sel — это селектор инпута
            0
            Эта фича хотя бы не влияет на ожидаемое пользователем поведение.
            +2
            Возможно, оффтопик, но тоже занятно.
            Ещё в IE10 кардинально поменялась строка userAgent.
            В двух словах – привычное буквосочетание «MSIE» там просто отсутствует.
            Теперь в способы определения версии и типа браузера придётся дописывать ещё один костыль.
              +2
              Мне казалось, что полагаться на UserAgent — плохая идея. Чем Modernizr не угодил?
                0
                О том, что плохая идея – я знаю.
                Но так исторически сложилось, и пока проще поддерживать существующий вариант, чем переписать.
                  +3
                  С учётом того, что новым IE нужны стандартные методы, а не устаревшие IE'шные, проще как раз не давать старьё из-за определения IE.
                +1
                на какой версии ОС это происходит? Windows 7 — " Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
                  +1
                  Судя по всему, я ошибся. Не сочтите за попытку ввести в заблуждение.
                  Кажется, это относится к IE11, с которым мне пришлось поработать некоторое время.
                    0
                    да, в превью версии IE11 UserAgent выглядит так: Mozilla/5.0 (Windows NT 6.3; Trident/7.0; .NET4.0C; rv:11.0) like Gecko
                0
                По пункту 1 — крестик рисуется только когда фокус находится в поле. После нажатия на крестик и потери фокуса — срабатывает change
                  0
                  Собственно, это и имелось в виду под событием input. Для любого input'а событие change происходит при потере фокуса. Но дело в том, что пользователю об этом, как правило, неизвестно, и поведение отличается от ожидаемого.
                    0
                    Более того, я, как знающий об этом программист, считаю такое поведение не очевидным и не совсем логичным
                  +3
                  > Довольно печально (хотя это и работает).

                  В этом — отличие пессимиста от оптимиста. Оптимист бы сказал: «Отлично, проблема решена!».

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

                  Т.е. стало во всём похоже на стандартные браузеры? Например,
                  document.body.title ='qwert';
                  
                  … в IE10, как я посмотрел, работает, как и во всех браузерах. Есть ли отличия? С чем связана оговорка, что в атрибуте может быть только строка? В каких браузерах может быть не строка?
                    +5
                    Да тут весь пост: «ай-ай-ай, теперь надо писать не под IE, а по стандартам!»
                    –9
                    Ну вот ВСЁ через жопу у некрософта. Мы выпустили клёвый браузер, смотрите какой он быстрый бла-бла-бла. И это не страшно, что он несовместим со стандартами. Версии к 25й мы это исправим, правда, придется пожертвовать скоростью, но вы же это переживете?
                    • НЛО прилетело и опубликовало эту надпись здесь

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое