Я тут совершенно случайно ввязался в масштабное исследование, посвященное внедрению флеша в страницы. Точнее, я просто не подозревал, что вокруг столь небольшой темы написано просто умопомрачительное количество некорректной информации.
Итак, необходимо внедрить Flash 9 (AVM2) и при этом достигнуть баланса со следующим списком требований:
- Должно играть до полной загрузки ролика (streaming);
- Должна работать коммуникация Flash с браузером, в обе стороны;
- Должно работать во всех более-менее заметных браузерах;
- Должно работать с типом контента application/xhtml+xml для xhtml;
- Нежелательны лишние запросы на сервер;
- Категорически нежелательны посторонние визуальные эффекты;
- Решение должно быть валидным;
- Если плагина нет - должен ставиться, если плагин устарел - должен обновляться;
- Очень хотелось бы обойтись без яваскрипта;
- Желательна отдача referer при загрузке swf, а то ходят слухи, что иногда не отдается;
- Желательна работа при режиме высокой безопасности в IE и при отключенном ActiveX;
- Отсутствие глюков - чтобы параметры передавались, прозрачность работала и т.д.;
- Семантичность - отсутствие лишних сущностей в коде;
- Отсутствие необходимости щелкать для активации в IE и Opera;
- При невозможности соблюдения всех вышеперечисленных условий должен соблюдаться принцип graceful degradation.
Изучение темы показало, что используются следующие основные способы внедрения флеша в страницу:
- через тег embed;
- через тег object;
- также можно воспользоваться JS-библиотекой типа SWFObject2;
- комбинация вложенных тегов object или object&embed.
Начнем с JS [9]Честно говоря, смысл использования SWFObject от меня ускользнул. Если не вкладывать никакого дополнительного смысла в море статей о нем, то все речи сводятся к
щелчку для активации, невнятному "упрощению интеграции" и "определении версии плеера". Первое быстро становится неактуально, т.к. майкрософт
убрал эту необходимость. Второе - простно враньё, ведь процесс только замедляется [5, 9], становится менее надежным [3] и работает не всегда [4, 9]. Третье - тема необычайно сложная и не от SWFObject в ней всё зависит. А нужно, чтобы работало [8].
Поэтому, по возможности, сторонние JS-библиотеки я постараюсь не использовать.
Режим высокой безопасности в IE [11]В этом случае всё печально - Flash работать не будет. Совсем, как не исхитряйся.
Нюансы в IE:
- Embed не работает (работает только noembed), но IE ничего не сообщает и не предлагает. Что плохо. И, кстати, атрибут PLUGINSPAGE в IE не работает [8];
- При использовании object IE7 выдает желтую полосу с предупреждение, что ActiveX отключен и ссылку на справку. Что неплохо.
Т.е. [11] из списка требований исключается ввиду нереализуемости.
embedЭто тег старый, на данный момент абсолютно нестандартный, но зато поддерживаемый почти всем чем только можно. Кстати, имеет все шансы
реинкарнироваться в html5. Всем хорош, только есть у него несколько родовых травм: сейчас невалиден [7] и, главное, совсем не работает мост JS-to-AVM2 [2] во всех версиях IE. Работает только SetVariable для AVM1. Также есть вышеописанная проблема с [11]. Т.е. применение этого тега возможно, но только в некоторых случаях: не нужен JS или не нужен IE. Увы, это не ко мне. Копаем дальше.
Комбинация вложенных тегов object или object&embedНа мой взгляд, вложенные теги - бестолковая комбинация [13], права на жизнь не имеет. Лишняя возня с определением реально используемого тега ID для JS не добавляет привлекательности. object&embed - это вообще не пойми что по причине вышеописанных проблем у embed. Изначально, наверное, идея была в том, чтобы обойти браузеры не поддерживающие тег object, но такие экземпляры вымерли ещё 10 лет назад даже на мобильных устройствах.
А вот пара тегов object и условных комментариев явно имеет право на жизнь, хотя и усложняет код.
objectТег рекомендован W3C, так что в теории всё должно быть хорошо. Но на практике имеется миллион глюков и куча устаревшей и мусорной информации вокруг его использования. Честно говоря, умаялся я этот мусор разгребать, всё описывать не буду, только основные находки и соображения:
- Указывать атрибут classid для IE нет необходимости. Отлично работает и просто type="application/x-shockwave-flash";
- Наличие атрибута data убивает streaming в IE [1]! Кроме того, IE ещё и уродливую рамку на месте объекта отображает, пока всё не загрузит [6];
- Отсутствие атрибута data приводит к незагрузке ролика в Firefox! А вот всем остальным браузерам достаточно параметра movie;
- Атрибут STANDBY, позволяющий разместить комментарий типа "Идет загрузка" пока грузится swf не работает в IE. В остальных не проверял, т.к. во всех остальных всегда работает streaming;
- Атрибут codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,124,0" отлично работает в IE, но не работает в остальных браузерах. А IE предлагает загрузить новую версию плеера, если текущая устарела. Наверное лучше, по возможности, использовать "#version=9,0,0,0" т.к. майкрософт распространяет версию 9,0,115,0 в составе SP3. Этим мы несколько уменьшим кол-во загрузок, т.е. будем меньше беспокоить наших пользователей;
- Атрибут codetype можно не использовать, т.к. type достаточно;
- Эксперименты с атрибутами тега param valuetype и type не увенчались успехом;
- Эксперименты с data="data:application/x-shockwave-flash," не увенчались успехом.
Возможные решенияВидно, что всё вертится вокруг борьбы с атрибутом data:
- Можно не бороться, а одновременно использовать и атрибут data, и параметр movie.
<object width="400" height="300" type="application/x-shockwave-flash" data="http://example.org/flash.swf">
<param name="movie" value="http://example.org/flash.swf">
</object>
Работать будет везде, но в IE работать будет уродливо. - Можно бороться только с Firefox присвоением data через JS
<object id="swf1" width="400" height="300" type="application/x-shockwave-flash">
<param name="movie" value="http://example.org/flash.swf">
</object>
<js> document.getElementById("swf1").data = "http://example.org/flash.swf" </js>
Причем на firefox можно и не проверять - отлично работает и без этого.
Способ в целом неплохой, но требует включенного JS под Firefox. - Можно бороться только с IE через условные комментарии
<!--[if IE]>
<object id="swf1" width="400" height="300" type="application/x-shockwave-flash">
<![endif]-->
<!--[if !IE]><-->
<object id="swf1" width="400" height="300" type="application/x-shockwave-flash" data="http://example.org/flash.swf">
<!--><![endif]-->
<param name="movie" value="http://example.org/flash.swf">
</object>
Это, пожалуй самое лучшее решение. Работает везде (похоже, что вообще в абсолютно всех браузерах) и работает красиво, плавно, без посторонних эффектов.
Понятное дело, что я за последний вариант. Замечания по нему:
- Небольшое дублирование кода. Настолько небольшое, что это и недостатком сложно назвать;
- Забыли про щелчки для активации;
- Забыли про альтернативный контент, и про инсталляцию плеера, если его нет;
- Забыли про обновление плеера, если устарел.
Обновление и инсталляция плеераЭто тема сложная, достойная рассмотрения в следующей (ещё не написанной) части статьи, поэтому сейчас ограничусь общими соображениями:
- Вообще-то плеер умеет обновляться и сам. Он проверяет наличие обновлений при загрузке очередного ролика, но не чаще чем раз в 30 дней. Можно и помочь браузеру обновит плеер, задав атрибут codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0". Это имеет смысл только для IE, т.к. codebase должен указывать только на свой домен, что в данном случае не соблюдается. IE на это плюет, а остальные блюдут. Причем, можно не повторять codebase у каждого тега object, а ограничиться однократным упоминанием.
- Если плеера нет, или он недоступен, то будет отображен так называемый альтернативный контент. Соответственно, нужно этим контентом сказать пользователю, что ему нужно установить плеер.
<a href="http://www.adobe.com/go/getflashplayer">
Для корректной работы сайта вам необходимо установить проигрыватель Adobe Flash<br />
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Установить" /></a>
А если используется IE, то теоретически можно и ничего не говорить, т.к. вначале отработает предложение установить плагин по codebase, а после этого пользователь должен пенять на себя.
Кстати, заметили, что все ссылки уже давно переехали с macromedia.com на adobe.com?
Щелчок для активацииЭто, пожалуй, самая большая проблема, также достойная рассмотрения в следующей (ещё не написанной) части статьи. На данный момент щелчка требуют IE6 и IE7 без последних обновлений и Opera9. Т.е. проблема вроде как изживает сама себя, но всё-таки хотелось бы решить красиво. Жаль, что программно узнать необходимость фикса невозможно.
Заключение
Вот ссылки на пример:
- HTML (Content-Type: text/html);
- XHTML (Content-Type: application/xhtml+xml) - напоминаю, xhtml в IE не работает.
Предложено достаточно элементарное, но весьма даже рабочее решение. Работа над недоработками ведется. Исследована применимость тега embed, который также небезынтересен.
Я специально оговорюсь: я знаю, что я не открыл Америку. Как минимум один человек из Чехии уже публиковал аналогичное решение, но проблема в том, что очень часто чтобы задать вопрос нужно знать ответ. Этой заметкой я описываю не только найденное решение, но и кучу сопутствующей информации. Надеюсь, кому-нибудь это поможет. Кроме того, работа не окончена, я ещё буду возвращаться к этой теме. Я был бы очень благодарен за любые отзывы, критику и сообщения об ошибках.