Javascript.RU

Javascript <-> Flash мост

Эта статья описывает, как вызывать из Javascript методы Flash и наоборот.

Используя эти способы, javascript может получить доступ к буферу обмена ОС, хранимым объектам SharedObject, управлять flash-интерфейсами и многое другое.

Какой бы способ коммуникации мы не выбрали, для начала JS должен уметь находить объект Flash на странице.

Для того, чтобы все работало кроссбраузерно, Flash-ролик нужно вставить с использованием обоих тегов: object и embed, например так:

<object 
    id="BridgeMovie" width="400" height="200"        
    classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"   
 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
    <param name="movie" value="bridge.swf" />
    <param name="allowScriptAccess" value="sameDomain" />
    <embed
        src="bridge.swf" 
        name="BridgeMovie" align="middle"
        play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
        width="400" height="200" scale="exactfit" 
        type="application/x-shockwave-flash"
        pluginspage="http://www.macromedia.com/go/getflashplayer">
    </embed>
</object>

В этом примере существенны детали:

  1. Имя ролика BridgeMovie дублируется как object.id и embed.name.
  2. Путь к ролику bridge.swf дублируется в object/embed
  3. Параметр allowScriptAccess="sameDomain"
  4. Дублируются размеры ролика

Теперь объект ролика можно получить из window["BridgeMovie"] для IE или document["BridgeMovie"] в остальных браузерах:

function getMovie() {
    var M$ =  navigator.appName.indexOf("Microsoft")!=-1
    return (M$ ? window : document)["BridgeMovie"]
}

Далее мы разберем средства для коммуникации с этим роликом.

Самый древний, знакомый большинству флешеров способ - это вызов javascript-функции посредством getURL с протоколом javascript:

getURL('javascript:функция("параметры");');
  • Работает во всех броузерах
  • Flash 5 и выше
  • Прост в применении
  • Не возвращает результат
  • Длина передаваемой строки ограничена 508 символами.

Вызов осуществляется так:

fsCommand("функция", "параметры")

Чтобы принять этот вызов, в Javascript должна быть специальная обвязка.

Редактор Macromedia Flash может генерировать ее автоматически при публикации ролика.

Для этого нужно в Publish Settings:

  1. Во вкладке Formats включить публикацию html-файла
  2. Во вкладке HTML выбрать Template: Flash with FSCommand

Генерируемый шаблон javascript-обвязки состоит из двух частей: функция обработки и дополнительного кода для IE.

Название функции имеет вид <ИмяРолика>_DoFSCommand. В нашем случае это BridgeMovie_DoFSCommand

Первый аргумент - имя вызываемой функции, второй - строка аргументов.
Простейший вариант выглядит так:

function BridgeMovie_DoFSCommand(command, args) {
    // вызвать функцию command с аргументом args
    window[command].call(null, args)
}

Вызов, например, функции show из Flash приведет к цепочке вызовов:

  1. (Flash) fsCommand("show","something")
  2. (JS) BridgeMovie_DoFSCommand("show","something")
  3. (JS) show("something")

Этот код нужен только для IE под Windows, в дополнение к BridgeMovie_DoFSCommand, так как в этом браузере fsCommand вызывает не Javascript, а VBScript.

if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 
&& navigator.userAgent.indexOf("Windows") != -1) {
        document.write('<script language=\"VBScript\"\>\n');
        document.write('On Error Resume Next\n');
        document.write('Sub BridgeMovie_FSCommand(ByVal command, ByVal args)\n');
        document.write('        Call BridgeMovie_DoFSCommand(command, args)\n');
        document.write('End Sub\n');
        document.write('</script\>\n');
}

Здесь VBScript просто передает вызов Javascript'у.

Итак, плюсы и минусы метода fscommand:

  • Flash 5 и выше
  • Не работает под Mac OS
  • Не возвращает результат
  • Нужен дополнительный JS-код

Этот способ работает, начиная с Flash 8. В отличие от всех предыдущих способов, он не только вызывает javascript, но и передает обратно возвращаемое значение, по возможности сохраняя его тип.

import flash.external.ExternalInterface;
var result = ExternalInterface.call("func", "param1", "param2", ...);

К сожалению, начиная с Flash 8, где он впервые появился, в ExternalInterface нашли большое количество разнообразных багов. Глюки сериализации, самопроизвольное изменение передаваемых данных и т.п.

Эти ошибки поправлены в новейших версиях Flash Player, но многие продолжают использовать более старые редакции Flash 8,9.

Актуальную информацию об ошибках можно получить из google, набрав "ExternalInterface bug".

  • Простота
  • Возвращает результат
  • Разнообразные баги, в отличие от предыдущих способов

Самый простой способ - установка переменной ролику:

getMovie().SetVariable("message","data")

Обратите внимание - именно SetVariable, не setVariable. Регистр здесь важен.

Чтобы Flash получил значение - можно проверять сообщения, например, на каждом кадре. Это около 12 раз в секунду.

Следующий код срабатывает на каждом кадре и ждет появления значения переменной message.

var message = null
_root.onEnterFrame = function() {
	if (message!==null)	{
		_root.txtRecieve.text = message // получили сообщение
		message = null
	}
}
  • Простота и надежность
  • Кросс-браузерность, Flash 5+
  • Дорога в одну сторону, не больше одного сообщения за кадр.

Применив ExternalInterface из Flash8+, можно объявить флеш-метод, который будет обрабатывать вызовы из javascript.

Формат вызова:

ExternalInterface.addCallback(функция JS, объект Flash, функция Flash);.

Например, следующий код устанавливает глобальную функцию recieveFromJS как обработчик JS-вызова sendFromJS.

import flash.external.ExternalInterface;
...

ExternalInterface.addCallback("sendFromJS", null, recieveFromJS);

function recieveFromJS(msg) {
	_root.txtRecieve.text = msg;
}

В JS достаточно сделать простой вызов:

getMovie().sendFromJS(value);
  • Можно тут же получить значение из Flash
  • Множество багов в ExternalInterface.

Можно также использовать LocalConnection, как это сделано во Flash-Javascript Integration Kit.

Этот пример пересылает текст из верхнего JS-поля направо во Flash, из нижнего Flash-поля - налево в JS.

Вводите любой, текст и жмите кнопку для пересылки нужным методом.

Послать из JS во Flash:
->
<-
// Flash Storage example

import flash.external.ExternalInterface;

ExternalInterface.addCallback("sendFromJS", null, recieveFromJS);

function recieveFromJS(msg) {
	_root.txtRecieve.text = msg;
}


_root.button.onRelease = function() {
	fscommand("recieveFromFlash", _root.txtSend.text);
}

_root.button2.onRelease = function() {
	ExternalInterface.call("recieveFromFlash", _root.txtSend.text);
}

_root.button3.onRelease = function() {
	var txt = _root.txtSend.text.split('"').join('\\"')
	getURL('javascript:recieveFromFlash("'+txt+'");');
}

var message = null

_root.onEnterFrame = function() {
	if (message!==null)	{
		_root.txtRecieve.text = message
		message = null
	}
}

Скачать .fla - исходник флешки.

function recieveFromFlash(Txt) {
        document.getElementById('txtRecieve').value = Txt;
}

function getMovie() {
        var M$ =  navigator.appName.indexOf("Microsoft")!=-1
        return (M$ ? window : document)["BridgeMovie"]
}


function sendSetVariable() {
        var value = document.getElementById('txtSend').value

        var movie = getMovie()
        movie.SetVariable("message", value)
}


function sendExternalInterface() {
        var value = document.getElementById('txtSend').value

        var movie = getMovie()

        movie.sendFromJS(value);
}

/* movie name_DoFSCommand */
function BridgeMovie_DoFSCommand(command, args) {
        window[command].call(null, args)
}


// Hook for Internet Explorer.
if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 && 
navigator.userAgent.indexOf("Windows") != -1) {
        document.write('<script language=\"VBScript\"\>\n');
        document.write('On Error Resume Next\n');
        document.write('Sub BridgeMovie_FSCommand(ByVal command, ByVal args)\n');
        document.write('        Call BridgeMovie_DoFSCommand(command, args)\n');
        document.write('End Sub\n');
        document.write('</script\>\n');
}

По просьбам читателей - примеры и исходники вынесены на отдельную страницу.

Успешной интеграции!


Автор: farhan fave (не зарегистрирован), дата: 2 сентября, 2021 - 18:00
#permalink

Thank you for taking the time to publish this information very useful!
리니지 프리서버


Автор: farhan fave (не зарегистрирован), дата: 2 сентября, 2021 - 18:00
#permalink

I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
리니지 프리서버


Автор: farhan fave (не зарегистрирован), дата: 2 сентября, 2021 - 18:01
#permalink

Thank you for taking the time to publish this information very useful!
리니지 프리서버


Автор: fave fave (не зарегистрирован), дата: 2 сентября, 2021 - 18:01
#permalink

I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
리니지 프리서버


Автор: fave fave (не зарегистрирован), дата: 2 сентября, 2021 - 18:04
#permalink

I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
리니지 프리서버


Автор: jogazy jogazy (не зарегистрирован), дата: 2 сентября, 2021 - 18:34
#permalink

I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
서버모아


Автор: fave fave (не зарегистрирован), дата: 3 сентября, 2021 - 10:54
#permalink

Yes i am totally agreed with this article and i just want say that this article is very nice and very informative article.I will make sure to be reading your blog more. You made a good point but I can't help but wonder, what about the other side? !!!!!!THANKS!!!!!!
서버모아


Автор: jogazy jogazy (не зарегистрирован), дата: 3 сентября, 2021 - 10:56
#permalink

Positive site, where did u come up with the information on this posting? I'm pleased I discovered it though, ill be checking back soon to find out what additional posts you include.
서버모아


Автор: sudoku 247 (не зарегистрирован), дата: 3 сентября, 2021 - 15:37
#permalink

sudoku 247 is an entertainment website suitable for all ages. Here, in addition to your entertainment, you can also find many other games that serve the purpose of training some skills for children such as Sudoku, Impossible Game, Tetris... Wish you have a good time. relaxing rewarding and fun!


Автор: fave fave (не зарегистрирован), дата: 13 сентября, 2021 - 12:29
#permalink

I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
레플리카사이트


Автор: fave fave (не зарегистрирован), дата: 13 сентября, 2021 - 12:29
#permalink

I can see that you are an expert at your field! I am launching a website soon, and your information will be very useful for me.. Thanks for all your help and wishing you all the success in your business.
레플리카사이트


Автор: jogazy jogazy (не зарегистрирован), дата: 13 сентября, 2021 - 12:56
#permalink

I’ve been surfing online more than three hours today, yet I never found any interesting article like yours. It’s pretty worth enough for me. In my opinion, if all webmasters and bloggers made good content as you did, the web will be a lot more useful than ever before.
명품레플리카


Автор: jogazy jogazy (не зарегистрирован), дата: 13 сентября, 2021 - 12:57
#permalink

An fascinating discussion is value comment. I think that it is best to write extra on this matter, it won’t be a taboo topic however generally people are not enough to talk on such topics. To the next. Cheers
명품레플리카


Автор: Гостьsd (не зарегистрирован), дата: 27 сентября, 2021 - 10:28
#permalink

I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me. I am appreciating it very much! Looking forward to another great article. Good luck to the author! All the best!
liver hospital in hyderabad


Автор: Гостьsd (не зарегистрирован), дата: 27 сентября, 2021 - 10:31
#permalink

I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me. I am appreciating it very much! Looking forward to another great article. Good luck to the author! All the best!
https://bit.ly/3un7T6A


Автор: Гостьsd (не зарегистрирован), дата: 27 сентября, 2021 - 10:31
#permalink

I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me. I am appreciating it very much! Looking forward to another great article. Good luck to the author! All the best!
https://bit.ly/3un7T6A


Автор: Гость (не зарегистрирован), дата: 27 сентября, 2021 - 10:31
#permalink

hello!! Very interesting discussion glad that I came across such informative post. Keep up the good work friend. Glad to be part of your net community.
https://bit.ly/3un7T6A


Автор: Atl Academy (не зарегистрирован), дата: 10 октября, 2021 - 15:30
#permalink

Really good point. your could recognize veb proqramasdirma from here https://atlacademy.az


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
2 + 1 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum