как разрешить javascript взаимодействовать с flash (Object # ‹HTMLObjectElement› не имеет метода

Я пытаюсь отправить простое тестовое сообщение с javascript на flash, но получаю сообщение об ошибке:

Object #<HTMLObjectElement> has no method "listenToJS"

Я прочитал несколько вопросов по этому поводу в стеке, но мне кажется, что либо браузер не получает правильную ссылку на мой flash-объект, либо в моем сценарии действий я не помещаю свою функцию flash в нужное место.

Итак, в html я встраиваю flash с SWFObj:

<div id="flash_content">
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1280" height="800" id="tourFlash" name="pano" class="pano">
        <param name="movie" value="VRDemo.swf" />
        <param name="menu" value="false" />
        <param name="wmode" value="transparent" />
        <param name="allowscriptaccess" value="always" />
        <!--[if !IE]>-->
        <object type="application/x-shockwave-flash" data="VRDemo.swf" width="1280" height="800" class="pano">
            <param name="menu" value="false" />
            <param name="wmode" value="transparent" />
            <param name="allowscriptaccess" value="always" />
            <param name="allownetworking" value="all" />
            <param name="flashvars" value="zoom=null&amp;pan=null&amp;sound=null" />
        <!--<![endif]-->
            <a href="http://www.adobe.com/go/getflashplayer">
                <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
            </a>
        <!--[if !IE]>-->
        </object>
        <!--<![endif]-->
    </object>
</div>

<script>

var flashObj; 

$(document).ready(function(){

    flashObj = document.getElementById('tourFlash');

    $('#interface').click(function(){
        console.log('click');
        talkToFlash();
    });
});

function talkToFlash(){
    flashObj.listenToJS('hello from js');
}

function listenFromFlash(flashMessage){
    console.log(message);
}
</script>

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

package com.company.vr {

    import flash.display.*;
    import flash.events.*; 
    import com.greensock.*;
    import com.greensock.easing.*;
    import flash.external.ExternalInterface;
    import flash.system.Security;

    Security.allowDomain("*");

     public class VR_TestDocument extends MovieClip {
            public function VR_TestDocument() {
              ExternalInterface.addCallback("talkToFlash", listenToJS);
            }


            public function listenToJS(message){
              trace ("from js: " + message);
              var flashMessage = message + " flash";
              ExternalInterface.call("listenFromFlash", flashMessage);
            }
     }
}

---ОБНОВИТЬ---

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

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html#addCallback ()

это работает, но мне кажется, что swfobject - лучший способ встроить flash. У кого-нибудь есть идеи?


person mheavers    schedule 15.01.2013    source источник
comment
Вы видели это? blago.net/coding / snippets /   -  person francis    schedule 16.01.2013


Ответы (2)


Если вы встроили flash в html в качестве кода выше, обратите внимание, что второй тег object также должен содержать атрибут id, исправленный код находится здесь:

<div id="flash_content">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1280" height="800" id="tourFlash" name="pano" class="pano">
    <param name="movie" value="VRDemo.swf" />
    <param name="menu" value="false" />
    <param name="wmode" value="transparent" />
    <param name="allowscriptaccess" value="always" />
    <!--[if !IE]>-->
    <object type="application/x-shockwave-flash" data="VRDemo.swf" width="1280" height="800" class="pano" id="tourFlash1">
        <param name="menu" value="false" />
        <param name="wmode" value="transparent" />
        <param name="allowscriptaccess" value="always" />
        <param name="allownetworking" value="all" />
        <param name="flashvars" value="zoom=null&amp;pan=null&amp;sound=null" />
    <!--<![endif]-->
        <a href="http://www.adobe.com/go/getflashplayer">
            <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
        </a>
    <!--[if !IE]>-->
    </object>
    <!--<![endif]-->
</object>

But of course, swfobject is the best way to embed flash. Correct html code looks like:

    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>js</title>       
        <script type="text/javascript" src="swfobject.js"></script>
        <script>
            function talkToFlash(){
                document.getElementById('flash_content').listenToJS('hello from js');
            }

            var flashvars =  {};
            var params = {
                allowscriptaccess: "always"         
            }           
            var attributes =  {};
            swfobject.embedSWF("VRDemo.swf", "flash_content", "550", "400", "10.0.0", false, flashvars, params, attributes);
    </script>   
    </head>
    <body>
        <div id="flash_content"></div>
    </body>
</html>

--Обновлять--

Вы должны выбрать правильный flash-элемент на странице. (Зависит от браузера). В качестве примера приведем код для получения правильного flashObj:

flashObj1 = document.getElementById('tourFlash');
flashObj2 = document.getElementById('tourFlash1');
flashObj = flashObj1.talkToFlash != undefined ? flashObj1 : flashObj2;      
person Serge Him    schedule 16.01.2013
comment
Код, который я использовал, был сгенерирован генератором кода swfobject - он не помещает идентификатор во второй экземпляр объекта, и когда я его добавляю, он терпит неудачу: bobbyvandersluis.com/swfobject/generator/index.html, code.google.com/p/swfobject/wiki/generator - person mheavers; 16.01.2013
comment
Я только что опробовал данный вами генератор. Если я устанавливаю идентификатор для второго тега ‹object› и удаляю его из первого - все работает, попробуйте. - person Serge Him; 16.01.2013
comment
Но я рекомендую использовать swfobject.embedSWF () - он более гибкий. swfobject.js u cad downlod отсюда ссылка - person Serge Him; 16.01.2013
comment
используйте swfobject.getObjectById () при статической публикации. Не нужно добавлять идентификатор во вложенный объект - person pipwerks; 17.01.2013
comment
Да, ты прав. В этом примере есть моя ошибка. Идентификаторы должны быть уникальными. И вы можете решить, какой элемент использовать (зависит от браузера). - person Serge Him; 09.10.2013

Это вполне может быть проблема с синхронизацией - Flash Player требуется немного времени для инициализации ExternalInterface, а затем немного больше времени для загрузки вашего SWF. Ваш пример кода выполняется в DOMReady, что НЕ является гарантией того, что SWF-файл загружен или что ExternalInterface инициализирован в Flash Player.

Я рекомендую запросить SWF-файл, чтобы убедиться, что он загрузился. На LearnSWFObject.com есть пример (с использованием динамической публикации): http://learnswfobject.com/advanced-topics/executing-javascript-when-the-swf-has-finished-loading/

ОБНОВЛЕНИЕ: перечитав ваш код и некоторые другие предлагаемые ответы, я заметил, что вы используете document.getElementById, чтобы получить свой <object>. При использовании вложенной разметки <object> это не сработает (кроме IE, который использует внешний <object>). swfobject.getObjectById был специально создан для решения этой проблемы. Попробуйте отредактировать свой JS, чтобы использовать swfobject.getObjectById.

person pipwerks    schedule 16.01.2013
comment
Спасибо - я попробую. Однако единственное, что вызывается при готовности документа, - это ссылка на flashObj, который является статическим (он находится на странице с самого начала), и обработчик щелчка для кнопки интерфейса, который также находится на странице с самого начала. Итак, теоретически, пока я ждал, пока загрузится моя флеш-память, прежде чем нажимать кнопку, этот код все равно должен работать, верно? - person mheavers; 16.01.2013
comment
Теоретически да. Например, вы можете создать ссылку, которая вызывает ваш ExternalInterface, а затем дождаться загрузки SWF перед тем, как щелкнуть ссылку. Если ваш ExternalInterface работает, вы знаете, что у вас проблема с синхронизацией. Если не сработает, можно поискать другие причины. - person pipwerks; 17.01.2013