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

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

Скачать библиотеку и получить дополнительную информацию можно на странице проекта SWFObject в Google Code.

Поправки по существу надеюсь увидеть в комментариях, сообщить об опечатках можно с помощью клавишесочетания Ctrl+Enter.

Что такое SWFObject?

SWFObject 2:

  • Предоставляет два оптимизированных метода внедрения Flash, основанных на разметке и использующих JavaScript
  • Предоставляет JavaScript API со всеми возможностями необходимыми для внедрения SWF файлов и получения информации о Flash плеере. [http://code.google.com/p/swfobject/wiki/api]
  • Использует один небольшой JavaScript файл (SWFObject 2.0 size: 8.7Kb / GZIPed: 3.4Kb, SWFObject 2.1 size: 9.5Kb / GZIPed: 3.8Kb)
  • Преемник SWFObject 1.5 [http://blog.deconcept.com/swfobject/] и UFO [http://www.bobbyvandersluis.com/ufo/]
  • В конце концов должен заменить Adobe Flash Player Detection Kit [http://www.adobe.com/products/flashplayer/download/detection_kit/]
  • Объединяет все существующие методы внедрения Flash и претендует на новый стандарт внедрения Flash.
  • Проект с открытым кодом Джефа Стирнса, Михаеля Вильямса и Бобби ван дер Слуйса, ранее известный как SWFFix [http://code.google.com/p/swffix/]

Почему вы должны использовать SWFObject?

  • Он более оптимизированный и гибкий чем любой другой способ внедрения Flash плеера
  • Он является универсальным решением для всех: будь вы HTML, Flash или JavaScript разработчик, это решение подходит для всех
  • Прекращает затянувшееся использование специфичной разметки для некоторых браузеров, позволяет использовать стандартную разметку и альтернативный контент
  • Использует ненавязчивый JavaScript и лучшие практики JavaScript
  • Прост в использовании

Подробное обоснование необходимости использования SWFObject 2 вы можете найти в статье Flash Embedding Cage Match опубликованной на A List Apart [http://www.alistapart.com/articles/flashembedcagematch/].

Почему SWFObject использует JavaScript?

SWFObject 2 использует JavaScript преимущественно для преодоления проблем, непреодолимых с помощью разметки:

  • Определяет версию Flash плеера и в зависимости от результата отображает Flash или альтернативный контент, чем предотвращает искажение Flash в плеерах старых версий.
  • Позволяет вернуться к альтернативному контенту с помощью DOM манипуляций в случае, если используется Flash плагин неподходящей версии (Примечание: если Flash плагин не установлен то вместо элемента object автоматически отображается вложенный альтернативный контент).
  • Позволяет использовать Adobe Express Install для установки последней версии Flash плеера
  • Решает проблему со старыми версиями движка Webkit, игнорирующими вложенные в object элементы param, используя проприетарный элемент embed. (Это единственный случай когда используется проприетарная разметка, это будет исключено в будущих версиях)
  • Позволяет публиковать Flash контент с помощью JavaScript тем самым исключать механизмы активации
  • Предоставляет продуманный JavaScript API для выполнения распространенных действий с Flash плеером и Flash контентом.

Какой из методов публикации предпочтителен, статический или динамический?

SWFObject 2 позволяет внедрять Flash двумя различными методами:

  1. При статическом методе публикации Flash и альтернативный контент внедряются с помощью стандартной разметки, а JavaScript используется для решения проблем непреодолимых с помощью разметки.
  2. Динамический метод публикации основан на замене альтернативного контента Flash контентом в случае если есть достаточно новая версия Flash плеера и поддержка JavaScript.

Преимущества статического метода публикации:

  1. Используется стандартная разметка
  2. Механизм внедрения Flash контента не зависит от JavaScript благодаря чему Flash будет доступен значительно большей аудитории:
    • если у вас установлен Flash плагин, но отключен JavaScript, вы все равно увидите Flash контент.
    • Flash будет отображен на устройствах с очень плохой поддержкой JavaScript, вроде Sony PSP
    • Приложения вроде RSS ридеров смогут отобразить Flash

Преимущества динамического метода публикации:

  1. Позволяет обойти механизмы активации активного контента в Internet Explorer 6/7 и Opera 9+. Обратите внимание, что Microsoft выпустил обновления исключающие механизм активации в браузерах Internet Explorer [http://www.swffix.org/devblog/?p=19]
  2. Отлично интегрируется в JavaScript приложения

Статический метод публикации Flash с помощью SWFObject

Шаг 1: Внедрение Flash и альтернативного контента с помощью стандартной разметки

SWFObject использует метод вложенных объектов (с условными комментариями для Internet Explorer) [http://www.alistapart.com/articles/flashembedcagematch/] это оптимальная кроссбраузерная разметка, соответствующая стандартам и позволяющая задать альтернативный контент [http://www.swffix.org/testsuite/]:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject - step 1</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  </head>
  <body>
    <div>

      <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">
        <param name="movie" value="myContent.swf" />

        <!--[if !IE]>-->
        <object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">

        <!--<![endif]-->
          <p>Alternative content</p>
        <!--[if !IE]>-->
        </object>
        <!--<![endif]-->

      </object>

    </div>
  </body>
</html>

Примечание: Метод вложенных объектов требует дублирования объявления object (внешний object предназначен для Internet Explorer а внутренний object для остальных браузеров), поэтому если вам нужно определить атрибуты или param для object то их нужно продублировать для внешнего и внутреннего объектов.

Обязательные атрибуты:

  • classid (только для внешнего object, значение всегда clsid:D27CDB6E-AE6D-11cf-96B8-444553540000)
  • type (только для внутреннего object, значение всегда application/x-shockwave-flash)
  • data (только для внутреннего object, определяет URL SWF файла)
  • width (для обоих элементов object, определяет ширину SWF)
  • height (для обоих элементов object, определяет высоту SWF)

Обязательные элементы param:

  • movie (только для внешнего элемента object, определяет URL SWF файла)

Примечание: Мы рекомендуем не использовать атрибут codebase для указания URL установки Flash с серверов Adobe, поскольку это противоречит спецификации которая ограничивает доступ доменом текущего документа. Вместо этого используйте альтернативный контент с сообщением, что пользователь может получить полную версию установив Flash плагин.

Как использовать HTML для конфигурирования Flash контента?

Вы можете использовать опциональные атрибуты элемента object [http://www.w3schools.com/tags/tag_object.asp]:

  • id
  • name
  • class
  • align

Вы можете использовать специфичные для Flash элементы param [http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_12701]:

Зачем нужен альтернативный контент?

Элемент object может содержать альтернативный контент который будет отображен если Flash плеер не установлен или не поддерживается. Альтернативный контент доступен поисковикам, поэтому он может быть хорошим инструментом при оптимизации сайта для поисковиков. Альтернативный контент нужен если вы хотите сделать сайт доступным для пользователей не использующий плагины [http://www.adobe.com/devnet/flash/articles/progressive_enhancement_03.html], хорошо индексируемый поисковиками [http://www.adobe.com/devnet/flash/articles/progressive_enhancement_04.html] и ненавязчиво показывающий пользователям, что они могут увидеть его во всей красе если установят Flash плагин.

Шаг 2: Подключение библиотеки SWFObject

Библиотека SWFObject состоит из одного внешнего JavaScript файла. Код SWFObject выполняется сразу после его загрузки, манипуляции с DOM выполняются после загрузки DOM, в браузерах которые это поддерживают, таких как IE, Firefox, Safari и Opera 9+ или по onload в остальных случаях:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject - step 2</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

    <script type="text/javascript" src="swfobject.js"></script>

  </head>
  <body>
    <div>
      <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">

        <param name="movie" value="myContent.swf" />
        <!--[if !IE]>-->
        <object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">

        <!--<![endif]-->
          <p>Alternative content</p>
        <!--[if !IE]>-->
        </object>
        <!--<![endif]-->

      </object>
    </div>
  </body>
</html>

Шаг 3: Зарегистрируйте ваш Flash контент и задайте параметры

Для начала добавьте уникальный id внешнему элементу object определяющему Flash контент, потом нужно вызвать метод swfobject.registerObject со следующими аргументами:

  1. Первый аргумент (Строка, обязательный) id используемый в разметке.
  2. Второй аргумент (Строка, обязательный) необходимая версия Flash плеера. Если установлена более старая версия Flash плеера SWFObject принудительно отображение альтернативный контент (производятся DOM манипуляции). Номер версии Flash плеера обычно содержит четыре элемента major.minor.release.build, SWFObject работает только с первыми 3 числами, поэтому и "WIN 9,0,18,0" (IE) и "Shockwave Flash 9 r18" (все остальные браузеры) будет преобразовано в "9.0.18".
  3. Третий аргумент (Строка, опциональный) используется для активации Adobe express install [http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75] и должен быть равен URL вашего express install SWF файла. Express install отображает стандартный диалог загрузки Flash плагина вместо Flash контента, если требуемая версия плагина не установлена. В архиве проекта уже есть готовый expressInstall.swf. Кроме того есть соответствующие expressInstall.fla и AS файлы (в директории SRC) на случай если вам нужно будет модифицировать имеющийся или создать свой express install. Обратите внимание, что express install срабатывает только один раз (при первом исполнение), требует Flash плеер версии 6.0.65 или старшей на Win или Mac платформах, минимально возможный размер SWF для его работы 310x137px.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject - step 3</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <script type="text/javascript" src="swfobject.js"></script>

    <script type="text/javascript">
    swfobject.registerObject("myId", "9.0.0", "expressInstall.swf");
    </script>

  </head>

  <body>
    <div>

      <object id="myId" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="780" height="420">

        <param name="movie" value="myContent.swf" />
        <!--[if !IE]>-->
        <object type="application/x-shockwave-flash" data="myContent.swf" width="780" height="420">

        <!--<![endif]-->
          <p>Alternative content</p>
        <!--[if !IE]>-->
        </object>
        <!--<![endif]-->

      </object>
    </div>
  </body>
</html>

Советы

  • Используйте SWFObject HTML и JavaScript генератор для автоматического создания кода [http://code.google.com/p/swfobject/wiki/generator]
  • Чтобы вставить несколько SWF просто повторите шаги 1 и 3
  • Простейший способ получать активный элемент object — это использовать JavaScript API: swfobject.getObjectById(objectIdStr) [http://code.google.com/p/swfobject/wiki/api]

Динамический метод публикации с помощью SWFObject

Шаг 1: Создание альтернативного контента с помощью стандартной разметки

Динамический метод публикации следует принципам прогрессивного улучшения (progressive enhancement) [http://www.adobe.com/devnet/flash/articles/progressive_enhancement.html] и заменяет альтернативный HTML контент на Flash контент в случае если есть достаточная поддержка JavaScript и Flash. При использовании динамического метода публикации нужно создать HTML контейнер с альтернативным контентом и задать для него id:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject dynamic embed - step 1</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  </head>
  <body>

    <div id="myContent">

      <p>Alternative content</p>
    </div>

  </body>
</html>

Шаг 2: Подключение библиотеки SWFObject

Библиотека SWFObject состоит из одного внешнего JavaScript файла. Код SWFObject выполняется сразу после его загрузки файла, манипуляции с DOM выполняются после загрузки DOM, в браузерах которые это поддерживают, таких как IE, Firefox, Safari и Opera 9+ или по onload в остальных случаях:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject dynamic embed - step 2</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

    <script type="text/javascript" src="swfobject.js"></script>

  </head>
  <body>
    <div id="myContent">
      <p>Alternative content</p>
    </div>

  </body>
</html>

Шаг 3: Внедрение SWF с помощью JavaScript

swfobject.embedSWF(swfUrl, id, width, height, version, expressInstallSwfurl, flashvars, params, attributes) у данного метода пять обязательных и четыре опциональных параметра:

  1. swfUrl (Строка, обязательный) URL SWF файла
  2. id (Строка, обязательный)  id  HTML элемента (содержащего альтернативный контент) который должен быть заменен на Flash контент
  3. width (Строка, обязательный) ширина SWF
  4. height (Строка, обязательный) высота SWF
  5. version (Строка, обязательный) версия Flash плеера необходимого для данного SWF (формат: "major.minor.release")
  6. expressInstallSwfurl (Строка, опциональный) задает URL вашего express install SWF и активирует Adobe express install [http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75]. Обратите внимание, что express install срабатывает только один раз (при первом исполнении), требует Flash плеер версии 6.0.65 или старшей на Win или Mac платформах, минимально возможный размер SWF для его работы 310x137px.
  7. flashvars (Строка, опциональный) переменные передаваемые Flash в виде пар имя:значение
  8. params (Строка, опциональный) элементы params вложенные в object в виде пар имя:значение
  9. attributes (Строка, опциональный) атрибуты элемента object в виде пар имя:значение

Примечание: Вы можете опустить опциональные параметры при условии, что это не изменит порядок параметров. Если вы не хотите использовать опциональный параметр, но хотите использовать параметр следующий за ним, просто задайте для него значение false. Параметры flashvars, params и attributes являются JavaScript объектами, их можно пропустить не только вышеуказанным методом, но и передав пустой объект: {}.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>SWFObject dynamic embed - step 3</title>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <script type="text/javascript" src="swfobject.js"></script>


    <script type="text/javascript">
    swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0");
    </script>

  </head>
  <body>
    <div id="myContent">
      <p>Alternative content</p>
    </div>

  </body>
</html>

Конфигурирование Flash контента

Вы можете использовать опциональные атрибуты элемента object [http://www.w3schools.com/tags/tag_object.asp]:

  • id (Еслиid не определен элемент object автоматически наследует id контейнера с альтернативным контентом)
  • name
  • styleclass (используется вместо class, поскольку это ключевое слово в ECMA4)
  • align

Вы можете использовать специфичные для Flash элементы param [http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_12701 ]:

Как используя JavaScript объекты установить переменные, параметры и атрибуты?

Вы можете создать JavaScript объекты используя объектный литерал:

<script type="text/javascript">

var flashvars = {};
var params = {};
var attributes = {};

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", flashvars, params, attributes);

</script>

Пары имя:значение можно добавить при создании объекта (примечание: не ставьте запятую после последней пары имя:значение):

<script type="text/javascript">

var flashvars = {
  name1: "hello",
  name2: "world",
  name3: "foobar"
};
var params = {
  menu: "false"
};
var attributes = {
  id: "myDynamicContent",
  name: "myDynamicContent"
};

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", flashvars, params, attributes);


</script>

Или после него:

<script type="text/javascript">

var flashvars = {};
flashvars.name1 = "hello";
flashvars.name2 = "world";
flashvars.name3 = "foobar";

var params = {};
params.menu = "false";

var attributes = {};
attributes.id = "myDynamicContent";
attributes.name = "myDynamicContent";

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", flashvars, params, attributes);


</script>

В одну строку это можно записать так:

<script type="text/javascript">

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", {name1:"hello",name2:"world",name3:"foobar"},
                   {menu:"false"}, {id:"myDynamicContent",name:"myDynamicContent"});


</script>

Если вы не хотите использовать опциональный аргумент можно передать false или пустой объект (Примечание: для SWFObject 2.1 можно будет использовать еще и null или 0):

<script type="text/javascript">

var flashvars = false;
var params = {};
var attributes = {
  id: "myDynamicContent",
  name: "myDynamicContent"
};

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", flashvars, params, attributes);


</script>

Объект flashvars предназначен для упрощения работы с переменными передаваемыми в Flash при желании вы можете игнорировать ее и передавать  flashvars через объект params:

<script type="text/javascript">

var flashvars = false;
var params = {
  menu: "false",
  flashvars: "name1=hello&name2=world&name3=foobar"
};
var attributes = {
  id: "myDynamicContent",
  name: "myDynamicContent"

};

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0",
                   "expressInstall.swf", flashvars, params, attributes);

</script>

Советы

  • Используйте SWFObject HTML и JavaScript генератор для автоматического создания кода [http://code.google.com/p/swfobject/wiki/generator]
  • Чтобы вставить несколько SWF просто повторите шаги 1 и 3

Переход от SWFObject 1.5 к SWFObject 2

  1. В SWFObject 2 НЕТ обратной совместимости с SWFObject 1.5
  2. Предпочтительно чтобы весь код JavaScript был в разделе head
  3. Имя библиотеки теперь в нижнем регистре: swfobject вместо SWFObject
  4. Методы доступны только через библиотеку (вместо экземпляра SWFObject в SWFObject 1.5)
  5. API абсолютно новое: [http://code.google.com/p/swfobject/wiki/api]
  6. SWFObject 2 заменяет указанный HTML блок с альтернативным контентом полностью, включая элемент контейнер, в случае если есть достаточная поддержка Flash и JavaScript, тогда как SWFObject 1.5 заменяет только содержимое указанoго контейнера. Если вы явно не указали атрибут id, элемент object автоматически наследует id указанного HTML контейнера с альтернативным контентом

Переход от UFO к SWFObject 2

  1. SWFObject 2 заменяет указанный HTML блок с альтернативным контентом полностью, включая элемент контейнер, в случае если есть достаточная поддержка Flash и JavaScript, тогда как UFO заменяет только содержимое указанoго контейнера. Если вы явно не указали атрибут id, элемент object автоматически наследует id указанного HTML контейнера с альтернативным контентом
  2. setcontainercss отсутствует в SWFObject 2, похожий функционал обеспечивает  SWFObject JavaScript API: swfobject.createCSS(selStr, declStr) [http://code.google.com/p/swfobject/wiki/api]

Поддерживает ли SWFObject 2 MIME тип application/xhtml+xml?

SWFObject 2 НЕ поддерживает XML MIME типы, это сознательное решение.

Есть несколько причин почему мы не поддерживаем их:

  • их использует очень малая часть веб-разработчиков
  • мы не уверены, что веб пойдет этим путем. Internet Explorer его не поддерживает и все остальные основные производители браузеров больше склоняются к новому, стандартному способу парсинга HTML (в HTML 5), отходя от парсинга HTML как XML, каким его видит W3C
  • отказавшись от поддержки XML MIME типов мы уменьшили размер файла и упростили тестирование и поддержку