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

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

назад к списку уроков и рецептов

Вступление

    1. Читаемость текста и сглаживание шрифта

    2. Preload и разделение загрузки.

    3. Память сайта. SharedObject, флэшовые cookie.

    4. Режим масштабирования сцены

    5. Вставка флэш-роликов в html-страницы

    6. Прямые ссылки на разделы флэш-сайта
        6.1 Изменение адресной строки при переходах внутри флэш-сайта
        6.2 Передача флэшке идентификатора текущего раздела

    7. Открыть в новом окне

    8. Контекстное меню. Правый клик.
        7.1 Минимизация контекстного меню
        7.2 Использование контекстного меню по назначению

    9. Tab. Перемещение фокуса внутри ролика

    10. Выделение и копирование текста на флэш сайтах

Итого


Вступление

  • Flash Player 6 — выпущен в марте 2002
  • Flash Player 7 — выпущен летом 2003
  • Flash Player 8 — выпущен осенью 2005
  • Flash Player 9 — выпущен в июне 2006
Официальная статистика распространения флэш плеера доступна на adobe.com. На момент написания статьи самые свежие данные за июнь 2006 года.

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


в начало

Читаемость текста и сглаживание шрифта

В классификации ошибок веб-дизайна, составленной Якобом Нильсеном, проблеме читаемости уделено первое место. Во флэше эта проблема усугубляется еще и тем, что отсутствуют стандартные средства масштабирования шрифта, которые есть в броузерах для html-страниц.

Однако, начиная с флэш плеера 7 версии, на флэш-сайтах эту проблему решить стало довольно просто. Если раньше, во флэше 6 или 5 версии, для достижения четкости текста приходилось совершать шаманские обряды и тщательно подбирать шрифт, то теперь управление сглаживанием включенного в ролик шрифта стало стандартной возможностью.

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

Если ваша задача — донести до человека текстовую информацию, не стесняйтесь сделать текст удобным для чтения. Кроме режима сглаживания необходимо подумать о размере шрифта, который пользователь не сможет просто так изменить по своему усмотрению.


в начало

Preload и разделение загрузки.

В настройках публикации ролика есть крайне полезный чекбокс — "Generate size report". Если поставить галку в этом чекбоксе, то при компиляции ролика в окне Output будет выведена подробная информация о том что в этом ролике сколько весит и в каком кадре что грузится. Там же будут перечислены все символы всех шрифтов, включенных в ролик. Пользуясь этими сведениями можно добиться того, чтобы в самом первом кадре вашего ролика грузилось только самое необходимое.

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

Прелоадер нужен ко всему, что грузится. Вы не можете угадать качество связи пользователя. Сайт, который замечательно работает на вашей машине или с локального сервера при самой медленной связи может вести себя крайне странно из-за того, что вы не учли, что на загрузку каждого килобайта может понадобиться какое-то время. Неправильные прелоадеры — первое, что выдает неграмотность флэш-разработчика.

Когда объём загружаемого файла пренебрежимо мал, незачем извещать пользователя о состоянии загрузки. Но, несмотря на то, что пользователь ни о чем не узнает, необходимо правильно организовать в коде ожидание окончания загрузки, иначе сайт будет работать непредсказуемо. И очень аккуратно стоит отнестись к критерию "пренебрежимости".

Хороший приём — пропускать загрузчик, когда всё загружается быстрее, чем появляется и проходит его анимация. Это может произойти либо в случае, когда загружаемый файл уже лежит в кэше броузера, либо когда качество связи с сервером позволяет получить файл почти мгновенно. В этих случаях пользователя будет раздражать мелькающий бессмысленный загрузчик. Чтобы избежать этого, можно перед тем как начать отображать процесс загрузки сделать небольшую паузу — четверти секунды бывает достаточно. Эта маленькая пауза будет практически незаметна для пользователя. По истечении этого времени нужно проверить, загрузился ли файл полностью, и если да, сразу перейти к следующим действиям, вместо того, чтобы показывать загрузчик. Паузу можно организовать при помощи setInterval() или просто отсчитав 2-3 кадра с момента вызова загрузки.

Сказанное не означает, что есть случаи, когда загрузчик можно вообще не делать. Неправильные прелоадеры — первое, что выдает неграмотность флэш-разработчика.


в начало

Память сайта. SharedObject, флэшовые cookie.

// флэш 6 и выше
var cookie = SharedObject.getLocal();

// объект cookie.data содержит сохраненные параметры
for (var i:String in cookie.data) {
    trace(i+" = "+cookie.data[i]);
}

// сохранение даты визита
cookie.data.visitDate = new Date().getTimer();
cookie.flush();

Я просто счастлив, когда сайт вспоминает, что я его уже посещал вчера, и вместо заставки на три минуты показывает мне сразу главную страницу.

Не говоря уже о том, что сайт просто обязан помнить, выключил ли я звук и какую громкость поставил. Если вы считаете, что звуковое оформление — неотъемлемая часть дизайна, можно по крайней мере снизить громкость до минимума, раз уж в прошлый раз я вообще предпочел выключить звук.

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


в начало

Режим масштабирования сцены

// флэш 6 и выше
Stage.scaleMode = "noScale";

При создании любого ролика учитываются оптимальные размеры графических объектов и текста. Но довольно часто разработчик забывает, что сцена ролика может быть отмасштабирована в зависимости от того, где и как отображается ролик. Если не позаботиться о том, чтобы сцена ролика не растягивалась, она будет растягиваться так, чтобы заполнить всё предоставленное ей в флэш плеере место, корёжа и уродуя ваши прекрасные пиксельно точные линии и текст. Если кому-то, например, придет в голову открыть ваш ролик напрямую в броузере, без обрамляющей его html-страницы, вы рискуете сильно напугать человека.

При вставке ролика в html страницу необходимо указать для него какие-то размеры. В случае, если вы забыли про режим масштабирования сцены, задание ролику в html любых размеров, отличных от тех, под которые он был сделан, приведет к искажениям.

Режим масштабирования связан не только с отображением графики в ролике. Давным-давно существует возможность делать во флэше резиновые сайты. Механизм, обеспечивающий такую функциональность, описан в соответствующем рецепте. Если вы захотите сделать сайт изменяющимся под размер окна броузера, вам всё равно понадобится включить режим масштабирования "noScale".

Растягивание сцены ролика может быть на пользу разве что в случае полностью векторной анимации.


в начало

Вставка флэш-роликов в html-страницы

<!-- HTML -->
<script src="swfobject.js"></script>
<div id="flash">Сюда будет вставлен Flash-ролик,
если версия флэш плеера в системе 8 или выше.
В противном случае пользователь увидит этот текст.</div>
<script>
var so = new SWFObject("site.swf", "site", 
                       "100%", "100%", "8", "#362711");
so.write("flash");
</script>

Используйте джаваскриптовый класс SWFObject для вставки ролика в страницу. Пожалуй, это всё, что можно сказать по этому поводу. Подробное руководство по использованию этого класса написал Джефф Стерн, а перевел Майкл Клишин. SWFObject избавляет пользователей Internet Explorer от необходимости добираться до вашей флэшки за несколько щелчков при каждом заходе на страницу, а так же выполняет проверку версии флэш плеера, установленного в системе пользователя. Кроме того, SWFObject пригодится вам при реализации механизмов, описанных в следующем параграфе.

Добавлю только, что использование этого класса позволяет избежать странных ошибок при использовании механизма ExternalInterface под управлением 9 флэш плеера в Internet Explorer. Если ваша флэшка вызывает джаваскриптовые функции, и вы получаете от броузера сообщения вроде "ошибка в строке 56, символ 3" без видимых на то причин, попробуйте применить SWFObject, это может помочь.


в начало

Прямые ссылки на разделы флэш-сайта

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

А между тем решить проблему не так и сложно. В этой статье я не буду останавливаться на всех тонкостях взаимодействия Flash — JavaScript. Попытка обобщить все знания по этой теме была сделана в статье про навигацию по флэш-сайту. Здесь я расскажу только о том, что точно можно и нужно сделать.

Обратите внимание: недавно на OSFlash.org появился новый проект — SWFAddress. Его основная цель — избавить разработчика от необходимости каждый раз самому организовывать грамотную навигацию по флэш-сайту. На момент написания статьи возможности SWFAddress еще далеки от совершенства, но можно надеяться, что разработчики доведут скрипты до ума (и до настоящей кроссброузерности).


в начало

Изменение адресной строки при переходах внутри флэш-сайта

Для начала нужно добиться того, чтобы адресная строка броузера всегда отображала текущее состояние флэшки. Рассмотрим простой пример: у вас на сайте три раздела "О нас", "О вас", "Про них". Вы хотите, чтобы пользователь мог поставить закладку на любой из разделов и, вернувшись, увидеть сразу его. Для этого в адресной строке должны произойти изменения. Поскольку при переходах внутри флэшки http-адрес страницы не меняется, нужно воспользоваться механизмом якорей. Якорь — это идентификатор, который добавляется к адресу страницы после знака "#".

<!-- HTML -->
<script>
setHash = function (name) 
{
    location.hash = name;
}
</script>

Этот короткий скрипт задает джаваскриптовую функцию, которая может установить любое имя якоря в адресной строке броузера. Для того, чтобы при каких-то событиях во флэше мы могли задать имя якоря через джаваскрипт, нужно из флэшки сделать вызов функции setHash(), передав ей строку. Сделать это можно несколькими способами.

// флэш 5 и выше
getURL("javascript:setHash('"+имя_якоря+"');");

// флэш 8 и выше
import flash.external.ExternalInterface;
ExternalInterface.call("setHash", имя_якоря);

Подробное сравнение и сведения о поддержке броузерами можно найти в упомянутой выше статье. Не забудьте, что для того, чтобы всё сработало, флэшке на странице нужно разрешить обращаться к джаваскрипту. Делается это добавлением одного параметра в теги <object> и <embed>, о которых, впрочем, мы можем не вспоминать, если пользуемся классом SWFObject.

<!-- HTML -->
<script src="swfobject.js"></script>
<div id="flash">Сюда будет вставлен Flash-ролик,
если версия флэш плеера в системе 8 или выше.
В противном случае пользователь увидит этот текст.</div>
<script>
var so = new SWFObject("site.swf", "site", 
                       "100%", "100%", "8", "#362711");
                       
// разрешаем флэшке обращаться к броузеру
so.addParam("allowScriptAccess", "always");

so.write("flash");
</script>
Итого: теперь флэшка может установить значение якоря в адресной строке. Это уже пол дела.
в начало

Передача флэшке идентификатора текущего раздела

<!-- HTML -->
<script src="swfobject.js"></script>
<div id="flash">Сюда будет вставлен Flash-ролик,
если версия флэш плеера в системе 8 или выше.
В противном случае пользователь увидит этот текст.</div>
<script>
var so = new SWFObject("site.swf", "site", 
                       "100%", "100%", "8", "#362711");
                       
// разрешаем флэшке обращаться к броузеру
so.addParam("allowScriptAccess", "always");

// передаем флэшке идентификатор раздела
so.addVariable("FlashVars_current", location.hash);

so.write("flash");
</script>

При загрузке ролик получит переменную _root.FlashVars_current, в которой будет содержаться идентификатор раздела, в который нужно перейти. Дальше уже ваш скрипт во флэше должен разобраться, что ему с полученным идентификатором делать.

Важно: первым символом идентификатора, полученного со страницы через location.hash будет "#". Можно отрезать этот символ уже в джаваскрипте, перед тем, как передавать идентификатор флэшу.

Важно: строка, которая будет содержаться в переменной _root.FlashVars_current теоретически может быть любой. Пользователь сам может набрать в адресной строке что угодно. Перед тем как ваш скрипт попробует открыть указанный раздел, нужно проверить идентификатор на вшивость. Если, к примеру, вы выбрали числовые идентификаторы, то переменная _root.FlashVars_current может содержать либо пустую строку, либо "#1", "#2", "#3" и т. д. Все остальные значения можно игнорировать.


в начало

Открыть в новом окне

// флэш 6 и выше
var isNewWindow:Boolean = 
    (Key.isDown(Key.SHIFT) || Key.isDown(Key.CONTROL));
if (isNewWindow) {
    getURL("http://noregret.org/#sectionX", "_blank");
} else {
    // сделать переход в другой раздел внутри флэшки
}

Когда вы хотите открыть ссылку в новом окне броузера, вы, скорее всего, привычным движением нажимаете Shift (или Control) на клавиатуре, и кликаете по ней. Есть вариации на эту тему, например, с кликом средней кнопкой мыши (колесиком) или с другими шорткатами. Но самым распространенным и известным вариантом остается Shift-клик или Control-клик.

Внимание, вопрос: как часто флэш сайт позволяет посетителю открывать по желанию ссылки в новом окне? Сама идея флэш-сайта подразумевает то, что страница не перезагружается при переходах между разделами. То есть, перехода на другой http адрес не происходит. Но это вовсе не означает, что пользователю это не может понадобиться никогда. Эта проблема тесно связана с реализацией прямых ссылок на разделы флэшового сайта, которая обсуждалась в предыдущем параграфе.

Собственно, никакой хитрости нет: нужно проверить, нажат ли на клавиатуре Shift или Control и в соответствии с этим открыть ссылку в новом окне броузера или сделать переход внутри флэшки. Конечно, пользователи отучены думать, что на флэшовых сайтах доступны такие привычные и удобные вещи, но если пользователь заметит, что это работает, он будет приятно удивлен.


в начало

Контекстное меню. Правый клик.

При нажатии на правую кнопку мыши (или контрол-клик на маках) появляется контекстное меню. Но удивительно не это.

Удивительно то, почему так мало флэш-сайтов использует это средство навигации по назначению. Контектное меню предоставляет пользователю исключительно быстрый доступ к элементам навигации. И раз контекстное меню на любой флэшке всё равно всегда есть, довольно странно не использовать это.

Довольно часто разработчики вообще забывают о таком явлении, как контекстное меню. В этом случае оно выглядит так:

 

Из названий пунктов меню понятно, что в случае с флэш-сайтом вы никогда не захотите, чтобы пользователь, например, сам рулил воспроизведением (пункты Rewind, Forward и Back) или менял качество (Quality). Обычно это приводит к неадекватной реакции ролика: кто бы мог подумать, что в логику происходящего вмешается любопытный пользователь. И очень редко вам может понадобиться предоставить пользователю какие-то из стандартных средств управления.


в начало

Минимизация контекстного меню

// флэш 6 и выше
Stage.showMenu = false;

или

// флэш 7 и выше
_level0.menu = new ContextMenu();
_level0.menu.hideBuiltInItems();

Самое простое — минимизировать контекстное меню. В этом случае оно будет выглядеть так:

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

Если вы не собираетесь использовать контекстное меню более осмысленно, по крайней мере минимизируйте его.


в начало

Использование контекстного меню по назначению

Stage.showMenu = true;

// флэш 7 и выше
var menu:ContextMenu = new ContextMenu();
_level0.menu = menu;

// скрыли стандартные пункты
menu.hideBuiltInItems();

var onCopyright:Function = function () 
{
    trace("onCopyright("+arguments+")");
    getURL("http://noregret.org/");
}

var item:ContextMenuItem = 
    new ContextMenuItem("© Nox Noctis 2006", onCopyright);

// список новых пунктов контекстного меню
menu.customItems = [item];

Два стандартных пункта — Settings и About — всегда будут в самом низу меню. Остальную часть меню совсем несложно создать самостоятельно. Для этого нужно создать необходимые пункты меню при помощи класса ContextMenuItem и записать их в список customItems объекта ContextMenu. Все имена говорят сами за себя, здесь нет ничего сложного. При создании пункта контекстного меню вы должны указать ссылку на функцию, которая будет срабатывать при выборе пункта.

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

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

Если вы планируете использовать контекстное меню с нестандартными пунктами, нельзя минимизировать его настройкой Stage.showMenu = false.

Пример грамотного использования контекстного меню на flash-mx.ru

Контекстное меню собирает элементы навигации, разбросанные по интерфейсу.


в начало

Tab, перемещение фокуса внутри ролика

// флэш 4 и выше
_focusrect = false;

При нажатии клавиши "Tab" во всех цивилизованных приложениях фокус ввода смещается к следующему активному элементу. Для управления порядком перемещения фокуса существуют свойства tabEnabled и tabIndex у клипов, текстовых полей, и кнопок.

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

По умолчанию флэш cопровождает переключение фокуса ввода появлением желтой рамки вокруг объекта, ставшего активным. Если фокус переключился на кнопку или ссылку, то нажатие кнопки Enter или пробела приведет к срабатыванию активного элемента. Возможно, это не плохо в некоторых случаях... Но в большинстве случаев смотрится уродливо и никак не сочетается с дизайном.

А уж если вы делаете игрушку, построенную на том, что действия пользователь должен совершать мышкой, это становится самой настоящей ошибкой. Желтая рамка также позволит увидеть все ваши прозрачные невидимые кнопки. Пример такой ошибки можно увидеть сайте absolut.com. В предлагаемой игре нужно искать изображения бутылок на большой картине. Бутылки являются прозрачными кнопками, по которым при помощи табуляции перемещается жирная желтая рамка.

Если в ролике вы используете v2 компоненты, встроенный класс FocusManager решает эту проблему за вас.


в начало

Выделение и копирование текста на флэш сайтах

// флэш 6 и выше
TextField.selectable = true;
TextField.selectable = false;

/* во флэш редакторе установка "selectable" 
для текстовых полей доступна с древнейших времен */

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

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

Здравый смысл подсказывает, что текст новости, анонса, стихотворения или песенки пользователь может захотеть скопировать с вашего сайта. Не отнимайте у него эту радость. И не давайте ему повод подумать, что html-сайт лучше флэш-сайта.


в начало

Итого

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


в начало
назад к списку уроков и рецептов


Корректировать материал помогли: