在Chrome </object>中更改其数据属性时,<object>标记不会刷新

时间:2012-04-28 19:35:35

标签: javascript html google-chrome svg

我在网页上有一个<object>标记,其data属性在JS(jQuery,具体而言)中以编程方式更改。 data标记始终指向SVG图像。

在Firefox中,当更改data标记时,新的SVG会加载并触发所有正确的事件。在Chrome中,直到我点击SVG画布才会发生这种情况 - 一旦发生这种情况,新SVG就会显示并且其相关事件全部触发。

这是为什么?当我更改<object>属性时,如何强制Chrome刷新data

3 个答案:

答案 0 :(得分:11)

嗯,今晚我真的无聊,我想做一些不是学业的事情,所以我为你挖掘了很多规格和论坛。

HTML4 spec似乎没有提到SVG,所以有一个死胡同。 HTML5 Spec Working Draft告诉我们,我们可以使用data来调用插件并加载内容。 HTML5 Spec Editor's Draft 执行了 mention SVG,告诉我们SVG属于embedded content类别。

由于Editor's DraftWorking Draft中定义的<object>元素添加了额外的详细信息,我们可以说加载<object>元素的行为不是一个公认的标准。(如果我错了,请有人纠正我。)

无论如何,在<object>规范中,除了关于浏览器应如何通过MIME类型等解释对象的所有常用技术术语...我们找到与此问题相关的部分:

  

4.6:如果负载失败(例如,出现HTTP 404错误,则出现DNS错误),触发名为错误的简单事件 在元素处,然后跳转到整个步骤集中的最后一步(后退)。

     

...

     

10:资源完全加载后,对任务进行排队,以便在元素上触发名为加载简单事件

Simple events仅表示事件不会冒泡(因此我们无法在任何父元素中侦听它)并且不可取消,并使用Event接口

所以,看看这个,我想如果我从DOM中选择<object>元素,它应该有onloadonerror个事件,如果不是object.addEventListener 。如果您查看SVG<object>的Mozilla开发人员网络文档,则大部分JavaScript文档都不完整。长号。

刚刚使用JSFiddle以及Chrome开发工具和Firefox Web控制台,我发现它们都支持onloadonerror,或者我认为是这样。

测试结果

Google Chrome(18.0.1025.165)和Firefox(12.0)

<强>支持

  • addEventListener('load', function(){})
  • obj.onload = function(){};

不支持(事件似乎无法触发

  • addEventListener('error', function(){})
  • obj.onerror = function(){}

正如您在fiddle中看到的那样,在Chrome中使用load事件会导致无限循环。它不应该这样做(根据editor's draft):

  

上述算法独立于CSS属性(包括'display','overflow'和'visibility')。例如,即使元素以“display:none”CSS样式隐藏,它也会运行,如果元素的可见性发生变化,则不会再次运行。

它看起来像某个人already filed a bug,所以如果你去确认这个错误,那将有助于Chrome开发者团队。

TL; DR

加载对象的行为尚未被接受,但您可以验证bug in the Chromium project。您可以尝试按@ Hello71建议并尝试从DOM中删除该元素并重新添加它,但I couldn't get it to work

答案 1 :(得分:5)

实际上,我遇到了完全相同的问题。看看http://jsfiddle.net/unesJ/,我用以下代码解决了它:

html:

<object id="graph" data="image1.svg" type="image/svg+xml"></object>

javascript:

var new_url = 'image2.svg';
$('#graph').attr('data', new_url);
$('#graph').load(new_url);

它适用于我

  • Chrome 24.0.1312.52 m
  • Firefox 17.0.1

希望它有所帮助!

答案 2 :(得分:2)

我尝试了很多东西。不幸的是,我不得不采取以下措施:

setTimeout(function(){
  $('body').trigger('click');
}, 40);

不,我没有更好的解决方案,但它完成了工作。