Разбираемся с SWFAddress
февраля 26, 2008
В сети море полезных фреймворков, классов и решений различных задач.
Однако очень многие из них имеют существенный недостаток – УЖАСНАЯ, если вообще присутствующая документация.
Недавно я прикоснулся к магии SWFAddress, библиотеке AS+JS, решающей проблему deep linking для FLASH и AJAX.
Для таких как я (гуманитариев и не-программистов) предлагаю свой опыт по освоению СВФАдреса.
Нет. Документацию на русский язык я переводить не буду. Не вижу в этом смысла. Документация более чем минималистическая. С тем же успехом ее можно было бы вообще не писать. В прочем + от нее все же есть – сводная таблица всех доступных в классе методов.
Первое что следует сделать – это скачать библиотеку. Настоятельно рекомендую качать 7-мегабайтовый архив с примерами и документацией. Потому что, как выяснилось в процессе, если бы я ограничился скачиванием только классов — меня бы постигла неудача, и я бы так и не понял в чем дело. А непоняток-ошибок на пути встретилось некоторое количество )
Первая ошибка. Исторически сложилось так, что я работал над сайтом, к которому намеревался прикрутить SWFAddress на завершающем этапе. Собираетесь использовать дип линкинг – сразу работайте с SWFAddress. Дело в том, что любое изменение адресной строки браузера (А это именно то, зачем нам вообще нужен дип линкинг) вызывает событие SWFAddress.onChange. То есть фактически и переключение разделов из флеш сайта (конечно если оно должно вести к изменению в адресной строке) , и переключение разделов извне (навигация по кнопкам ВПЕРЕД НАЗАД ,навигация по якорям на хтмл-странице и т.д.) вызывает это событие. В сущности на нем как раз и будет строиться обработка события переключения между разделами.
Ошибка вторая. Я доверился заявлению Flash CS3 Support. Фактически же, если публиковать ролик на странице с помощью AC_RunActiveContent.js, которое генерируется Flash IDE – дип линкинг не работает. Изменения в адресной строке – да, но ролик не реагирует на навигацию из браузера. Я дошел до этого знания случайно. Потеряв веру в свой мозг, я просто взял рабочий пример, и заменил в нем флешку на свою – и все заработало. Путем исключений я нашел камень преткновения. Каким то образом AC_RunActiveContent.js из примера отличается от того, что генерируется FLASH CS3 IDE. Так что пользуйтесь скриптом из примеров. Что касается работы с SWFObject и UFO – не проверял. У вас есть отличная возможность сделать это за меня, а потом отписаться здесь, если пожелаете.
Теперь о некоторых тонкостях и внутренностях. В архиве есть коды для всех трех версий AS. Мои опыты ставились на AS2.0
1. Класс написан как TopLevel-класс, или для тех кто не понимает этого словосочетания, – он не создает экземпляров. Пример такого класса -Math, все функции в нем вызываются подобным образом: Math.sin(), Math.round() и т.д. То же справедливо и для SWFAddress.
2. Адресная строка.
Для решения задачи дип линкинга, к существующему URL добавляется якорь # за которым следует строка, которую разработчик волен генерить сам, по своим правилам, и сам же по своим правилам ее и разбирает. Есть два режима. setStrict(true) – в конце адреса жестко добавляется слеш (/) и setStrict(false) – никаких слешей без ведома разрабочика.
3. Основные полезные методы.
В классе присутствует набор методов для разбора строки. Весьма удобно.
К примеру в адресной строке имеем
http://flashsite.com/#news?page=&img=2
SWFAddress.getValue():String - вернет значение строки аккурат после # со всеми Вашими изысками (парами имя=значение)
news?page=1&img=2
SWFAddress.getPath():String - вернет значение строки аккурат после # без дополнительных параметров
news
SWFAddress.getQueryString():Array - вернет строку с дополнительными параметрами
page=1&img=2
SWFAddress.getParameterNames():Array - вернет массив с именами дополнительных переменных
page,img
SWFAddress.getParameter(value:String):String - вернет значение дополнительного параметра указанного в value
getParameter(«page») // 1;
getParameter(«img») // 2;
Для того чтобы изменить адресную строку из FLASH существует метод setValue(value:String) – помните, что вызов этого метода автоматически приведет к вызову события onChange, так что фактически переключение между разделами сводится к замене значения адресной строки и последующей обработке события.
Остальные методы описывать не стану, они весьма просты и даже данных документации хватит для их освоения.
4. События.
Я уже говорил о событии onChange. Должен отметить, что событие это вызывается сразу же, при первом же упоминании класса, равно как и событие onInit. Большого смысла в событии onInit я не уловил. В самом начале оно вызывается и тут же за ним вызывается onChange. Возможно есть смысл для более четкой структуризации, и отделении инит-процедур от собственно обработки переключений между разделами.
Более подробно поговрим о событии onChange, хотя в случае с onInit все работает абсолютно так же, за исключением значения cвойств SWFAddressEvent: path=null; value=null; type=init;
События доступны в двух ипостасях:
SWFAddress.onChange = function():Void { trace("SWFAddress.onChange"); }
В данном случае мы просто определяем статичную функцию onChange.
Второй вариант – подписать любой свой объект на событие. Во многом это удобнее, чем описывать вложенные функции с обработчиком события.
К примеру мне удобно подписать экземпляр класса, который напрямую работает с SWFAddress. Для этого я сначала создаю функцию обработчик:
public function onChange():Void \ { trace("Class's onChange"); }
И далее подписывась на событие с помощью метода класса SWFAddress – addEventListener(type:String,listener:Function);
Поскольку в этом учавствует стандартный mx.utils.EventDispatcher, нужно подписаться так, чтобы наша функция onChange знала кто в доме хозяин – то есть надо жестко определить this. Делается это при помощи mx.utils.Delegate.create().
Итак подписка на событие для нашего экземпляра будет выглядеть так
SWFAddress.addEventListener("change",Delegate.create(this,onChange));
Теперь мы можем из тела функции onChange обращаться ко всем свойствам и методам нашего экземпляра. Ура.
Продвинемся дальше. В том случае, если мы подписываемся на событие, в качестве параметра в наш обработчик приходит экземпляр SWFAddressEvent, который несет в себе ценную информацию ![]()
Модифицируем наш обработчик.
public function onChange(evt:SWFAddressEvent):Void { //вернет путь после # из адресной строки БЕЗ параметров trace("path:"+evt.path); //вернет путь после # из адресной строки С параметрами trace("value:"+evt.value); }
Также событие несет информацию о своем типе (type=»change» или «init»), target (это всегда отсылка на SWFAddress) а также массив parameters («ассоциативный») с параметрами из queryString. Если в адресной строке есть news?param=value, то значение param можно получить так : SWFAddressEvent.parameters.param
Какие замечены баги.
1. Самый неприятный. В опере любое переключение между страницами ИЗ браузера (навигация вперед назад, якоря) вызывает полную перезагрузку страницы. Не очень то красиво, особенно если это флеш сайт с какими то особенными переходами между страницами. К счастью внутренние флешовые переходы проходят как обычно.
2.Если вручную вставить адрес в браузерной строке в FireFox – адресная строка перестает изменяться, когда переключаешься между разделами. Вроде как адреса заносятся в history, навигация вперед.назад работает, но это не отображается в адресной строке. В принципе – я лично замечал вообще странное поведение адресной строки в Фоксе, и без дип линкинга, например иногда в ней просто невозможно перенабрать адрес.
Работоспособность проверена на:
- Mozzilla FireFox 2.0.0.12
- Opera 9.10
- IE 6.0
- Safari (win) 3.0.3
В завершении могу только дать ссылку на первый свой опыт с SWFAddress, где вы можете потестировать работоспособность библиотеки в разных браузерах. Будет полезно, если здесь вы запостите свои баг репорты, ну или зададите вопросы о том, что осталось непонятным. Цель этого топика – сделать эту бесспорно полезную опцию более доступной всем категориям разработчиков )) Поэтому -включайтесь )
http://kvadra.net/samples/goodpeople/_flash/#chillout/two?pgid=2t&imgid=36
Popularity: 64% [?]
Entry Filed under: AS2.0,ActionScript,opensource,Полезное,грабли

25 комментариев
1. qzack | февраля 26, 2008 at 16:37
нужно будет на это решится.
«Нада себя заставить» )))
2. @st@l@vist@ | февраля 26, 2008 at 17:55
Проблема отшествия панели навигации в мир иной – это проблема FireFox, не SWFAddress.
В Opera 9.25 навигация через кнопки back | forward, мягко говоря работает не правильно. (Тестировалось на твоем примере
)
3. murejib | февраля 26, 2008 at 18:01
@st@l@vist@ а какие симптомы?
4. @st@l@vist@ | февраля 26, 2008 at 18:21
Когда мотаю History больше чем на один шаг, адрес в строке меняется, а флеш остается в одном и том же разделе.
Кроме того, если прощелкать «назад», а потом до конца «вперед», то висимс без флеша секунд 5-6 (Movie not loaded).
Лечить не получиться, уже и я, и многие другие разбили лбы
5. murejib | февраля 26, 2008 at 18:24
Думаю, это проблемы оперы+SWFAdress.
Увы, многие браузеры, многие проблемы ))
6. @st@l@vist@ | февраля 26, 2008 at 19:18
Если быть точнее, это проблемы Оперы + Флеш. SWFAddress тут не при чем, виноват лишь в том, что не прыгнул выше головы
Меня, в общем то, и интересовали подробности работы в Опере под Винду и в различных браузерах под Мак, Линукс.
Мак публику рассчитывал найти на ДеФоруме
7. Punk T-34 | ноября 6, 2008 at 15:07
А как в SWFaddress реализовуется анимация после нажатия кнопки «назад» в браузере?
Ну, напрмер, я иду на какую-то страницу и мне показывают прыгающий смайлик, и только после того как он пропрыгал инициируется пеереход на следующую страницу.
Но как управлять анимацией, когда я нажимаю в браузере кнопку «назад»?
Например, когда возвращаюсь назад, то хочу видеть того же прыгающего смайлика между страницами. Чтобы вернули меня на предыдущую страницу только тогда, когда он закончит прыгать.
Как такое можно реализовать? Потому что видел на нескольких сайтах подобное.
8. murejib | ноября 6, 2008 at 15:25
сам SWFAddress, конечно же не реализует анимаций. Все что он делает, это меняет адресную строку и сообщает флеш-ролику о смене состояния.
Здесь нужно писать самому такой обработчик события смены страницы, по которому анимация будет сначала отыгрываться в полной мере, а потом уже переключать сайт на другой раздел. В тех же гут. пиплах что-то подобное – анимация иконки текущего раздела сначала проигрывается в обратном порядке – потом меняется контент и так далее.
9. Punk T-34 | ноября 6, 2008 at 15:29
а этот обработчик события пишется на яваскрипте или во флэш?
10. murejib | ноября 6, 2008 at 15:36
обработчик пишется на флеше.
Все что нам нужно — это событие onChange, в статье этот момент описан, — надо просто расслабиться, выкинуть из головы все лишнее и спокойно прочитиать все с начала ))) я старался написать все как можно проще )
Тут механизм какой – в браузере сменилась адресная строка – это можт произойти или по желанию юзера (кнопки назад/вперед, букмарки и так далее) или по мановению флеш ролика (тоже сичтай юзера) который опять же средствами СВФАдреса меняет стрку браузера.
Тут же хитрый JS рассказывает ролику о том что адрес сменился – а наш ролик, уже вооруженный обработчиком onChange – вызовет эту самую чейндж функцию и сделает все о чем его попросили – распарсит адрес, пошле ролик куда надо, покажет что его просили.
Фактически – сам ролик менят строку и он же реагирует на смену строки – то есть такой вход через выход ))
11. Alexander | февраля 5, 2009 at 15:37
Я как новичок во флэше так ничего и не понял, сорри….
Ну вот я открыл Flash – передо мной белый лист и как же мне объяснить теперь Flash у, что он теперь работает с swf adress?
что мне и где прописать чтоб он использовал swfaddress?
12. Андрей | июня 15, 2009 at 13:11
А можно глянуть исходник? У меня не получается генерить произвольную строку взятую из xml.
13. BlooDHounD | июня 15, 2009 at 21:41
мдя. случайно наткнулся на статью, и увидел странное определение TopLevel-классу.
TopLevel-класс – это класс, который не имеет пакета. а тот, который не создаёт экземпляры это статический. Вам повезло что Math является и тем и тем
14. murejib | июня 16, 2009 at 7:12
BloodHound, спасибо за ликбез. Повторюсь, я гуманитарий ) и могу ошибаться в каких то священных кодерских заповедях.
15. murejib | июня 16, 2009 at 7:15
@Андрей – исходник сайта я, конечно же, не дам, но вы можете воспользоваться исходниками, выложенными в архиве вместе с кодами класса.
16. Андрей | июня 17, 2009 at 13:34
2murejib, да это понятно, я и не имел ввиду исходник сайта, просто были не понятны некоторе моменты, например как задавать дополнительные параметры. Но уже разобрался, спасибо.
Эта статья очень помогла.
17. Romano | июня 22, 2009 at 17:10
Я так и не могу понять. Вот когда в пхп задаешь переменные после знака вопроса, то они разделяются амперсандами (&). А тут как быть? тут получается надо парсер писать, чтоб она смотрел есть такая переменная и есть ли значение? А потом еще чтоб записывал и вставлял в адресную строку, так чтоли?
18. murejib | июня 22, 2009 at 21:09
Здесь все работает точно так же, пары переменная=значения отбиваются амперсандами.
В самом классе есть методы для поиска переменных и их значений – читайте внимательнее:
SWFAddress.getValue():String – вернет значение строки аккурат после # со всеми Вашими изысками (парами имя=значение)
news?page=1&img=2
SWFAddress.getPath():String – вернет значение строки аккурат после # без дополнительных параметров
SWFAddress.getQueryString():Array – вернет строку с дополнительными параметрами
page=1&img=2
SWFAddress.getParameterNames():Array – вернет массив с именами дополнительных переменных
SWFAddress.getParameter(value:String):String – вернет значение дополнительного параметра указанного в value
Для того чтобы изменить адресную строку из FLASH существует метод setValue(value:String)
19. Romano | июня 23, 2009 at 7:27
Это я все видел. Т.е. над писать метод, который будет смотреть наличие переменной в строке, затем изменять или добавлять данные там, и потом уже полностью обновлять строку через setValue.
20. murejib | июня 25, 2009 at 9:25
Ну это зависит от того, какая задача стоит )
Собственные методы класса позволяют собрать все переменные и взять их значение.
Если внутри нашей флешки нужно воспользоваться этими значениями, надо написать метод, кторый будет знать, что делать с ними.
Допустим у нас есть галерея, и мы хотим давать ссылку на определенное фото.
Если пользователь ввел в адресную строку
http://murejib.com/showcase/flashworks/sites/goodpeople/index.html#chillout/one?pgid=2t&imgid=2u
(ссылка, кстати рабочая)
SWFAddress при первом запуске получит в распоряжение chillout/one?pgid=2t&imgid=2u.
Метод, который у меня подписан на событие изменения строки получит эти данные и поймет, что сейчас надо создать экземпляр класса, который рендерит шаблон страницы chillout и отдаст ему управляющую строку one?pgid=2t&imgid=2u
Построив страницу, экземпляр класса поймет, что его просят показать альбом с идентификатором one, он найдет его описание в XML (там тоже есть такой идентификатор)
Далее он сообразит, что альбом надо открыть на странице с кодовым названием 2t (pgid=2t, тут используется хитрая система кодирования для точного определения страниц/картинок, с учетом того, что они могут пополняться и не будут иметь жесткого номера) и далее он откроет картинку под номером 2u (imgid=2u).
Как только мы нажмем в навигаторе на кнопку перехода к следующей картинке, внутренний метод просчитает ее кодовый номер и просто напросто используя SWFAddress.setValue поменяет значение адресной строки.
SWFAddress в свою очередь зафиксирует ее изменение и снова отрапортует всем подписчикам – мол строка изменилась. А внутренние методы уже сообразят – надо ли новую страницу рендерить или просто открыть какой то новый ее подраздел/картинку.
21. kerk | августа 14, 2009 at 8:36
спасибо за статью, давно читал ее, но все никак не мог решиться переделывать свои скрипты с использованием этой библиотеки
===
пара уточняющих вопросов:
есть несколько готовых скриптов PHP+JS+AJAX
работают и ошибок нет
как пример: на главной, есть панелька с вкладками, при клике на вкладку, отправляется запрос в БД на содержимое этой вкладки (AJAX)
запрос отправляется методом POST, ссылку на страницу с конкретной вкладкой, естессно не дашь =)
использую библиотеки от YAHOO, т.к. в движке форума используются именно они и менять на другие в своих скриптах нет смысла
так собственно сам вопрос, для использования SWFAddress, не обойдешься простым подключением этой библиотеки?
нужно полностью переделывать все скрипты, т.е. для использования AJAX (отправка запроса в пхп, прием ответа и т.д.), нужно пользоваться именно этой библиотекой, а не YAHOO?
22. murejib | августа 15, 2009 at 10:47
Не работал с библиотеками Yahoo и с Ajax )))
не могу сказать ничего по этому поводу.
23. discopop | февраля 14, 2010 at 14:00
Отцы, помогите!! swfaddress работает, но не могу понять – если я ввожу сразу адрес в браузере, к примеру: http://www.mysite.com/index.html#/news, то почему внутри flash’а swfaddress.getValue() возвращает тупо слеш, хотя вроде как должен /news возвращать. или я чет попутал? пасу getValue сразу же после события ADDED_TO_STAGE.. WTF?
24. Vasya | мая 12, 2010 at 19:21
Очень крутой сайт!!!
могу я попросить тебя выслать его исходник на почту? adamov.vasya@gmail.com
проверил в моих браузерах работает, только не совсем понял как все реализовано.
25. murejib | мая 13, 2010 at 12:48
Нет, раздавать исходники сайтов я не привык.
Только, если об этом просит тот, кто заказывает сайт.