页面刷新后,ExternalInterface在IE中不起作用

And*_*rew 4 javascript flash internet-explorer actionscript-3

我在IE中有一个奇怪的情况,在我点击"刷新"后,JS无法使用ExternalInterface调用闪存.我知道电影正在加载,执行该操作的代码ExternalInterface.addCallback()似乎没有任何错误

以下是重现步骤的简要说明:

  1. 打开IE并首次加载电影,可以使用ExternalInterface回调方法.
  2. 如果我点击刷新,回调方法不可用,我收到错误Object doesn't support this property or method.
  3. 如果我清除缓存并刷新页面,它们将再次可用.
  4. 如果我再次点击刷新而不清除缓存,则它们不可用.
  5. 如果我关闭浏览器并重新打开,它们将再次可用.

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

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

编辑:

我还应该提到,刷新后,'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);
Run Code Online (Sandbox Code Playgroud)

小智 6

问题是一旦swf文件缓存在浏览器中,ExternalInterface类将停止工作.

要克服这个障碍,您必须通过以下方式修改您的html文件和swf文件:注意:此解决方案在IE7中进行了测试

HTML文件 - 向swf文件添加参数以使其唯一.因此浏览器会认为每次加载页面时都需要下载新的swf文件.

例如,如果您正在使用SWFObject库(您不需要),那么您将进行以下调整:

var cachecontrol = Math.floor(Math.random()*99999);
var flashvars = {};
var params = {};
var attributes = {id:"movie"};
swfobject.embedSWF("movie.swf?nocache"+cachecontrol, "flashcontent", "100%", "100%", "10.1.0", "expressInstall.swf", flashvars, params, attributes);
Run Code Online (Sandbox Code Playgroud)

同样,添加以下元标记以确保您的html文件未缓存:

SWF文件 - 如果您从主swf加载swf文件,则必须应用相同的逻辑:var cachecontrol:String = Math.floor(Math.random()*9999).toString( ); loader.load(new URLRequest("movie.swf?nocache ="+ cachecontrol));

以下是解决方案的来源:http: //www.emanuelz.com.mx/blog/cache-control-tips-for-flash-120 注意:您不必再进行上述操作了.


AHM*_*AHM 6

如果有人想知道为什么会发生这种情况,至少对于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);
Run Code Online (Sandbox Code Playgroud)

这将使播放器等待,直到可以可靠地添加回调,然后调用一个调用的javascript函数player_ready来表示它已准备好使用.