<object> tag doesn't refresh when its data attribute is changed in Chrome

google-chrome, html, javascript, svg

Solution

Well, I was really bored tonight and I wanted to do something that wasn't schoolwork, so I dug through a lot of specs and forums for you.

The HTML4 spec doesn't seem to have any mention of SVG, so there's a dead end. The HTML5 Spec Working Draft tells us that we can use `data` to invoke plugins and load content. The HTML5 Spec Editor's Draft does mention SVG, telling us that SVG falls under the category of embedded content.

Because the Editor's Draft adds additional detail to the `<object>` element as defined in the Working Draft, we could say that the behavior of loading `<object>` elements is not an accepted standard. (Somebody please correct me if I'm wrong.)

Anyway, in the `<object>` specification, aside from all the usual technical jargon about how the browser should interpret the object by MIME-type etc... We find the part that's relevant to this question:

4.6: If the load failed (e.g. there was an HTTP 404 error, there was a DNS error), fire a simple event named error at the element, then jump to the last step in the overall set of steps (fallback).

...

10.: Once the resource is completely loaded, queue a task to fire a simple event named load at the element.

(Simple events merely mean that the events do not bubble (so we can't listen for it in any parent elements) and are not cancelable, and use the `Event` interface)

So, looking at this, I figured that if I select the `<object>` element off the DOM, it should have an `onload` and `onerror` event, if not `object.addEventListener`. If you look at the Mozilla Developer Network docs for SVG and `<object>`, much of the JavaScript documentation is incomplete. Bummer.

Just goofing around with JSFiddle and the Chrome Dev Tools and Firefox Web Console, I found that they both supported `onload` and `onerror`, or so I thought.

Results of testing

Google Chrome (18.0.1025.165) and Firefox (12.0)

Supports:

- `addEventListener('load', function(){})`

- `obj.onload = function(){};`

Does not support (events don't seem to fire):

- `addEventListener('error', function(){})`

- `obj.onerror = function(){}`

As you can see from the fiddle, in Chrome using the `load` event causes infinite loops. It is not supposed to do this (according to the editor's draft):

The above algorithm is independent of CSS properties (including 'display', 'overflow', and 'visibility'). For example, it runs even if the element is hidden with a 'display:none' CSS style, and does not run again if the element's visibility changes.

It looks like somebody already filed a bug, so if you would go and confirm the bug it would help the Chrome Developers Team.

TL;DR

The behavior for loading objects is not an accepted standard yet, but you can go verify a bug in the Chromium project. You could try doing as @Hello71 suggested and try removing the element from the DOM and re-adding it, but I couldn't get it to work.

Problem

I have an `<object>` tag on a web page, whose `data` attribute is changed programmatically in JS (jQuery, specifically). The `data` tag always points to a SVG image. In Firefox, when the `data` tag is changed, the new SVG loads and all the proper events fire. In Chrome, this doesn't occur until I click on the SVG canvas -- once that happens, the new SVG displays and its associated events all fire. Why is this? How can I force Chrome to refresh the `<object>` when I change its `data` attribute?

Original source

Related problems