【问题标题】:ExternalInterface not working in IE after page refresh页面刷新后,外部接口在 IE 中不起作用
【发布时间】:2011-05-26 04:00:51
【问题描述】:

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

以下是重现步骤的概要:

  1. 首次打开 IE 并加载电影,JavaScript 可以使用 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,因为 Flash 电影是 HTML5 音频不可用时的后备。

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);

【问题讨论】:

  • 当你调用 JS 方法 SWF 时,我的意思是说在哪个事件上?
  • @Andrew:你找到解决这个错误的方法了吗?不使用 SwfObject 可以解决吗?
  • 没有。我从没干过。鉴于我最初的观察和@Paul 在他的回答中的评论,我认为最好的办法是在页面的onload 事件触发后尝试加载内容(这是 swfobject 所做的)。在我的例子中,我只是在 IE 用户的 SWF 名称中随机分配了一个查询字符串变量,并且错误不再是一个因素,尽管这违背了理智的缓存策略。两种解决方案都不是最优的。

标签: javascript flash actionscript-3 internet-explorer


【解决方案1】:

如果有人想知道为什么会发生这种情况,至少对于 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 函数来表示它已准备好使用。

【讨论】:

  • 非常感谢您添加答案。我没有尝试过,但是您的解释和解决方案非常有意义。自从问了这个问题之后我就一直困扰着我必须绕过缓存,如果我有机会重新访问代码,我会使用这个解决方案。
【解决方案2】:

问题是,一旦 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);

另外,添加以下元标记以确保您的 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 注意:您无需再执行上述操作。

【讨论】:

  • 谢谢。这实际上就是我最终所做的。这是一个害虫,因为我们通过 CDN 提供所有 SWF 文件,而这种技术会阻止它们为我们缓存文件。我只需要为 IE 做这件事。让我发疯。
  • 当其他一切都失败时,这对我有用。即使在 ie8 和 ie9 中也有同样的问题。该死的,即。
【解决方案3】:

在不同版本中存在大量带有 ExternalInterface(通常是 flash,ime)的 IE 错误。大多数推荐的修复建议使用 SwfObject js 库,它修复了我所知道的所有问题。 http://www.timelesssky.com/blog/internet-explorer-flash-8-externalinterface-bug

【讨论】:

  • 有谁知道 SwfObject 的不同之处在于它可以克服这个问题吗?对我个人而言,将库添加到并不总是需要它的页面似乎是一种耻辱。
  • 自从我做一个需要这些东西的项目以来已经有一个 很长 时间了,但是如果记忆有用的话,它与他们如何/何时加载对象/嵌入标签。 iirc,这与 IE 如何缓存插件内容有关。
  • 我应该提到添加 SwfObject 确实需要对我的代码进行大量重构。 SwfObject 在 onload 之后嵌入代码,并且知道页面是否准备就绪的唯一方法是将所有内容挂在其回调上。这与我的代码的 HTML5 部分的工作方式不一致,并且使事情变得比我喜欢的要混乱得多。我会看看 SwfObject 并尝试弄清楚它是如何解决这个问题的(假设它在这种情况下确实如此)。
  • 明白了;不过,我认为,出于我们正在讨论的原因,它专门以这种方式与生命周期挂钩。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
  • 2014-08-23
  • 2020-02-15
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2019-02-20
相关资源
最近更新 更多