95 заметок с тегом

ie

Короткий способ определять IE

А какой сейчас самый короткий способ определять Эксплорер? Я понимаю, что привязываться к браузеру нехорошо, но у меня конкретная задача, которую никак не обойти — нужно проиграть звук в браузере (PCM wave), а ИЕ на запрос «сможешь проиграть?» к тегу AUDIO, говорит maybe. Т. е. давайте сюда свой звук, может и смогу. Я-то знаю, что не сможет — аудиотег в этом браузере «вавки» не играет, нужен EMBED.

Все короткие способы, которые раньше работали (условная компиляция, сравнение вертикального пробела с буквой v, хитрый хак с массивом и прочее) в 11-й версии работать перестали. Даже строку агента поменяли — там теперь нет MSIE.

В общем, я пока остановился на такой версии:

if (top.VBArray) {
    // IE
} else {
    // остальные браузеры
}

Но буду признателен за что-то более короткое или очевидное.

IE9 и таблицы

IE9 и таблица (18.31КиБ)

В продукте, которым я занимаюсь, минимальная версия Эксплорера, которую я решил поддерживать — девятая. В будущем я хочу поднять это требование до десятой, а пока приходится жить с тем, что есть — клиенты не готовы к резким переменам и я их понимаю.

Наткнулись на странную проблему в этой версии Эксплорера — некоторые таблицы выглядят как на снимке выше — ячейки в строках иногда выпирают вправо безо всякой видимой причины.

Дело оказалось в пробелах между ячейками — верстальщик отформатировал шаблон, чтобы он лучше читался, и все браузеры всё показали правильно, один девятый Эксплорер сошёл с ума. Лечится проблема запросто — либо убираем форматирование в шаблоне, либо убираем его прямо в браузере.

Я выбрал второй путь. Пусть лучше шаблон выглядит читаемо, а костыль для девятого Эксплорера всегда можно будет убрать лёгким движением руки. Выглядит он вот так, кстати (используется jQuery, само собой):

$("table tr").contents().filter(function() {
    return this.nodeType == 3;
}).remove();

Ленивая загрузка в ИЕ11

В IE11 интересную штуку сделали — ленивую загрузку. Можно пометить картинку (включая внедрённые тегом SVG), теги для воспроизведения видео и аудио, скрипты и многое другое специальным атрибутом lazyload, который означает «начать загружать, когда загрузится всё важное».

Иногда может быть удобно, для оптимизации скорости загрузки страницы, попросить браузер не загружать пока что-то объёмное. Я, например, в одном из наших проектов поставил этот атрибут аватарам пользователей. Пример использования:

<img src="avatar-3132.png" width="200" height="200" lazyload="1">

Можно добавить этот атрибут к банерам (на что мало кто согласится), большим графическим оформительским элементам (чтобы пользователь быстрее начал читать статью), фоновой музыке (правда она редко бывает вообще уместна) и т. п.

IE 10 CSS hack

Придумал CSS-хак для Эксплорера 10-й версии, срабатывающий только в режиме совместимости, похоже, что все существующие хаки в нём не работают.

@media , {
    .:valid, body {
        background: red; /* будет красным в Internet Explorer 10 (режим совместимости) */
    }
}

Проверил при помощи сайта «Браузер шотс» ложные срабатывания, как будто всё в порядке, их нет. Не проверял на IE11, не знаю будет ли там работать. Если у кого-то под рукой есть, напишите в комментариях, пожалуйста, интересно же. Ну и под другими браузерами всё равно будет нелишним проверить, напишите срабатывает или нет.

Так же придумал новый хак для обычного режима IE 10:

@media all\0 {
    _:valid, body {
        background: red; /* будет красным в IE 10 */
    }
}

И ещё один:

_:valid\0, body {
    background: green; /* будет зелёным в IE10 */
}

Так же не тестировал на IE11 (мне негде).

Оптимизация картинок поворотом

Есть такой старый трюк, который с развитием CSS получил новое прочтение. Дело в том, что при упаковке изображения в графические форматы, в основном, сканируют и упаковывают изображение, двигаясь по его линиям слева направо. Первом об этом на русском языке написал, думаю, Лебедев, вот что написано в книге «Реактивные вебсайты», соавтором которой я являюсь:

Изображения GIF хорошо поддаются оптимизации. В параграфе №8 «Ководства» Артемия Лебедева есть небольшое, но интересное исследование особенностей этого формата. Вывод из параграфа простой: чем больше на картинке горизонтальных линий одного цвета, тем лучше сжимается изображение. Алгоритм компрессии LZW, применяемый в GIF, вообще лучше сжимает регулярные горизонтальные структуры в пределах одной линии.

Соответственно, если есть возможность повернуть картинку, то, бывает, она сжимается лучше. Где-то была хорошая статья с колесом на эту тему, не могу найти. Смысл там в том, что изображение с колесом можно поверкнуть как угодно, разницы нет, у колеса, поставленного на попа, нет «верха» и «низа», а вращение даёт возможность упаковать картинку эффективнее.

Но не всегда так везёт, гораздо чаще, согласитесь, встречаются изображения, которые повернуть нельзя. Значит о способе забываем?

Вот тут нам и пригодятся нововведения в ЦСС. Берём свою картинку, сохраняем ещё три копии повёрнутые на 90°, 180° и 270°, а потом все четыре изображения оптимизируем, выбираем то, которое меньше занимает. А дальше просто поворачиваем его при помощи ЦСС (я ещё фильтр для старых ИЕ добавил и некоторые свойства для других браузеров):

.rotate90 {
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); /* IE 5.5+ */
    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; /* IE 8 */
    -ms-transform: rotate(90deg); /* IE 9 */
    -o-transform: rotate(90deg); /* Opera 10.5+ */
    -webkit-transform: rotate(90deg); /* Chrome, Opera 15+, Safari 3.1+, Android 2.1+, iOS 3.2+ */
    -moz-transform: rotate(90deg); /* FF 3.5+ */
    transform: rotate(90deg); /* FF 16+, IE 10+, Opera 12.1-14.99 */
}

Картинка поворачивается браузером и визуально остаётся как была.

Вообще, конечно, можно поворачивать на любой угол, если фон картинки прозрачный или совпадает с окружающим фоном, но в старых ИЕ для этого придётся использовать другой фильтр — Matrix, формула расчёта параметров такая:

progid:DXImageTransform.Microsoft.Matrix(
  M11 = cos(угол),
  M12 = -sin(угол),
  M21 = sin(угол),
  M22 = cos(угол),
  sizingMethod = 'auto expand'
);

Метод не лишён недостатков, конечно. Во-первых, всё это может сказаться на производительности, особенно в старых Эксплорерах (в последнем даже сомнений нет — скажется). Во-вторых, как видно из версий, которые я добавил в ЦСС, не все версии браузеров поддерживают поворот, правда их доля совсем невелика и продолжит снижаться.

Непонятный баг с AJAX в IE8

В процессе переезда одного из наших проектов на новый сервер, Интернет Эксплорер восьмой версии стал выдавать какие-то невнятные ошибки при использования AJAX. К решению проблемы подключили меня, так как сообщение об ошибке совершенно не давало ключа к её исправлению:

Ошибка в IE (3.55КиБ)

В этом месте в коде не было ничего криминального, создание объекта для «аякса», асинхронная посылка запроса и проверка свойств того что пришло. Методом проб и ошибок удалось выяснить, что ошибка возникает при попытке обращения к свойствам «status» и «responseText» (а так же «responseXML», в коде он не использовался, но я просто попробовал).

Промучавшись с полчаса, я догадался переключить IE на работу с объектом ActiveX Microsoft.XMLHTTP, вместо XMLHttpRequest, у первого диагностика получше — ему всё-таки много лет, а XMLHttpRequest в восьмой версии браузера тогда ещё не обкатался.

На этот раз я получил нумерную ошибку (скриншота не сохранилось), по номеру которой я нашёл сообщение на сайте Микрософт, что ошибка связана с неверной кодировкой, пришедшей со стороны сервера. В «Хроме» посмотрел кодировку — оказалось, что кодировка с сервера приходит как «cp1251»:

Кодировка cp1251 (1.55КиБ)

Интернет Эксплорер такую кодировку не понял, один из админов вписал её руками, поскольку при смене версии ПХП заменили сервер FastCGI на php-fpm, стоило сменить эту кодировку на «windows-1251» как всё заработало.

Видимо, встретив странную кодировку, IE не смог понять как ему читать то, что пришло, он вообще не заполнил некоторые свойства, а объект, попытавшись получить к ним доступ, не понимал в чём дело и выдавал пустую ошибку, которая и символизировала это «я не понял что произошло».

Двухбуквенные домены и ИЕ

Про проблему с двухбуквенными доменами в браузере Микрософта знают наверное, очень многие. Если вкратце, считается, что на двухбуквенных доменах второго уровня «Эксплорер» не ставит куки.

Отчасти так оно и есть.

Сделано это вот для чего. Некоторые страны (например, Великобритания) запрещают регистацию домена второго уровня для своих нужд, домен должен находиться на третьем уровне в зоне специальных доменов второго уровня. Если бы я родился и жил в Лондоне, мой блог мог бы располагаться по адресу bolknote.co.uk.

Вот отсюда и родилось это ограничение — так как на домене третьего уровня в некоторых странах располагается куча чужих друг другу сайтов, они могли бы читать и писать куки друг друга через общий домен (и воровать данные авторизации, например), но браузеры не озаботились механизмом предотвращения этой угрозы.

В «Экплорере» (скорее всего это произошло в шестой версии) защиту устроили просто — если в домене второго уровня две буквы и он не располагается на домене общего назначения (.com, .net и т. п.), то это специальный домен из вышеописанного случая и ставить куку на него нельзя.

Но тогда как же, чёрт возьми, поступает «Яндекс» со своих двухбуквенным «ya.ru»? Есть какая-то особая магия?

Разочарую — её нет, есть исключения.

Ребята из «Микрософта» через какое-то время поняли, что проверять домен на двухбуквенность — плохая идея, оказалось, что существуют двухбуквенные домены без специального значения и специальные домены с другим количеством букв (например — географические домены). Пришлось встроить в браузер список исключений, найти его можно по урлу res://urlmon.dll/ietldlist.xml.

Список исключений в IE (41.52КиБ)

Т. е. если домен встречается в теге «tld» или содержит только две буквы на втором уровне, то куку ставить нельзя, но если он встретился в теге «domain» — то можно. Посмотрите на скриншот, домен «Яндекса» содержится в списке исключений. Естественно, список может меняться при обновлении браузера.

Остальным браузерам так же приходится решать эту проблему. Например, ФФ содержит примерно такой же список:

# примерное количество значений в этом списке у ФФ:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | wc -l
   4019

# двадцать последних (по алфавиту) значений:
bolk@Bolk ~  $ grep -aF chel.ru /Applications/Firefox.app/Contents/MacOS/XUL  |  strings | fgrep . | fgrep -v / | sort -u | tail -20
z.bg
z.se
za.com
za.net
za.org
zachpomor.pl
zagan.pl
zakopane.pl
zaporizhzhe.ua
zarow.pl
zgora.pl
zgorzelec.pl
zgrad.ru
zhitomir.ua
zj.cn
zlg.br
zoological.museum
zoology.museum
zp.ua
zt.ua

Не знаю все ли четыре тысячи относятся к обсуждаемому списку (кстати, в нём всего 133 российских домена), но такой список точно существует.

Тот же список есть и в «Хроме» (на моём «Маке» он содержится в файле «Google Chrome Framework» и состоит из более 3,5 тысяч значений), в «Сафари» ничего похожего я обнаружить не смог, то ли такого механизма там нет, то ли спрятано глубже, чем мне позволяет искать моя лень. «Опера» держит свой список в файле «public_domains.dat», в нём на настоящий момент 4291 значение.

Таким образом, если вы владелец двухбуквенного домена и вам не повезло, у вас не работают куки как положено, пишите на адреса техподдержки производителей браузеров, а пока делайте редирект на домен третьего уровня (например, на «www»).

В IE10 не будет попадать под conditional comments

«Микрософт» решила, что conditional comments не должны обнаруживать IE10. То есть, по идее, условия «[if IE]», «[if IE 10]», «[if IE gt 5]» работать не должны, а «[if IE lte 9]» по-прежнему будет работать.

Поведение изменено из-за того, что этот функционал несовместим с HTML5. Ну да, в спецификации на парсер эта возможность не описана, но стоит ли её убирать? Вот уж вряд ли. Она много лет спасала верстальщиков от самоубийства.

Because some features in earlier versions of IE aren’t compatible with HTML5 parsing, we’ve removed them from IE10 mode. Sites that rely on these legacy features will still work when running in legacy modes. This way, sites that work today will continue to work with IE10 even if the developers of the site don’t have the time to update them.

Причём «Микрософт» тут же признаётся, что парсер ни при чём:

This means conditional comments can still be used, but will only target older versions of IE.

Если часть условия conditional comments всё-таки будут срабатывать, то причём тут парсер HTML5? Условия, которые оставили совместимы с HTML5, а те, которые убрали — нет?

Скорее «Микрософт» этим шагом заявляет, что «мы так всё идеально поддерживаем, что нет нужды отделять IE от других браузеров». Может быть это и так. Но я был бы рад, если бы conditional comments появились в других браузерах, а не исчезли был из IE.

Помимо этого из IE10 исчезнут Element Behaviors и XML Data Islands.

Добавлено позднее: мы тут поговорили с Вадимом Макеевым, кажется, я ошибаюсь. В режимах эмуляции старых браузеров (вероятно в этот момент работает отдельный движок), conditional comments работают, в режиме IE10 — нет.

Браузер в Windows Phone 7.0

У нас в компании появились первые смартфоны на Windows Phone 7.0. Естественно, очень интересно посмотреть что поддерживает тамошний браузер.

Пишу по мотивам одного из отзывов внутри компании.

HTML5Test — 15 баллов, ни одного бонусного (нет canvas, svg, video/audio, тегов HTML5, Geo API, SSE/WebSocket, localStorage), тест modernizr показывает отсутствие border-radius, rgba, box-shadow, opacity, gradients, transforms, transitions, flexbox, border-image, text-shadow и ещё многого другого.

Нет touch events, отсутствует Array.forEach, Object.defineProperty и ещё по мелочи.

Код юзер-агента выглядит вот так:

Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; HTC; 7 Mozart T8698)

IE 10 Platform Preview 1

Microsoft уже предлагает скачать Internet Explorer 10 Platform Preview 1.

Помнится, многие рассуждали о том, что MS опять забросит свой браузер на годы. Как видите, нет, только вышел IE9, как уже можно скачать превью следующей версии.

Ранее Ctrl + ↓