我在IE中有一个奇怪的情况,当我点击“刷新”后,JS无法使用ExternalInterface调用Flash。我知道电影正在加载,并且执行ExternalInterface.addCallback()的代码似乎已完成,没有任何错误

以下是重现步骤的摘要:

  • 打开IE并首次加载电影,ExternalInterface回调方法可用于JavaScript。
  • 如果我单击刷新,则回调方法不可用,并且出现错误Object doesn't support this property or method
  • 如果清除缓存并刷新页面,它们将再次可用。
  • 如果我随后在未清除我的缓存的情况下再次单击刷新,则它们不可用。
  • 如果我关闭浏览器并重新打开,它们将再次可用。

  • 之前我已经遇到过这种情况,并且我很确定下载和实例化swf所需的额外延迟就是允许正确设置ExternalInterface的原因。我之前解决此问题的方法是在swf网址的末尾添加一个随机数,这样它就不会从缓存中使用,但这不是真正的解决方案。

    有谁知道如何解决这个问题?

    编辑:

    我还应该提到刷新后,“ExternalInterface.available”为“true”,但“ExternalInterface.objectId”为“null”。

    我尝试将对象id的值随机化,并嵌入name和容器div的ID,在每种情况下,ExternalInterface.objectId仍为null

    更多信息:

    我看不出插入影片的方式会有什么不同,但我想我会确保其中包含代码。我的电影不受“单击激活”问题的影响,在这种情况下,我不想使用SWFObject,因为在HTML5音频不可用的情况下,Flash电影是后备的。
    var docContainer = document.createElement('div');
    docContainer.innerHTML = '<object '
            + 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
            + 'codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" '
            + 'id="mp3player" '
            + 'width="300" '
            + 'height="500">'
        + '<param name="allowScriptAccess" value="always" />'
        + '<param name="movie" value="mp3player.swf" />'
        + '<param name="quality" value="high" />'
        + '<param name="bgcolor" value="#ffffff" />'
        + '<embed '
            +'src="mp3player.swf" '
            + 'quality="high" '
            + 'bgcolor="#ffffff" '
            + 'width="300" '
            + 'height="500" '
            + 'swLiveConnect="true" '
            + 'name="mp3player" '
            + 'id="mp3player" '
            + 'allowScriptAccess="always" '
            + 'type="application/x-shockwave-flash" '
            + 'pluginspage="http://www.adobe.com/go/getflashplayer" />'
        + '</object>';
    document.body.appendChild(docContainer);
    

    最佳答案

    如果有人想知道为什么会这样,至少对于Internet Explorer,似乎Flash播放器是作为ActiveX控件加载的,该控件与DOM和JavaScript模块完全分开。缓存.swf时,似乎ActiveX控件可以在Javascript准备好接受其事件之前加载并运行它。

    这意味着,当Flash尝试使用ExternalInterface添加回调时,由于未加载JavaScript和DOM,它将失败。

    我通过等待第一个ENTER_FRAME事件,然后在此处注册我的回调来解决此问题。像这样:

    protected function registerExternalCallbacks(event:Event):void {
    
        removeEventListener(Event.ENTER_FRAME, registerExternalCallbacks);
    
        if (ExternalInterface.available) {
            ExternalInterface.addCallback("flash_play", play);
            ExternalInterface.addCallback("flash_setVolume", setVolume);
    
            ExternalInterface.call("player_ready");
        }
    }
    
    // and then when the .swf loads, register the function on the event:
    addEventListener(Event.ENTER_FRAME, registerExternalCallbacks);
    

    这将使播放器等到可以可靠地添加回调之前,然后调用名为player_ready的javascript函数来表明已准备好使用它。

    07-24 16:59