This doesn't work (in chrome 39 on OSX):
var x = new Image();
Object.observe(x, function(){console.log('i never run');})
x.src = 'http://www.foo.com';
console.log('has been set: ' + x.src);
But this will:
var x = new function nonNative(){};
Object.observe(x, function(){console.log('i will run');})
x.src = 'http://www.foo.com';
And so will this:
var x = new XMLHttpRequest();
Object.observe(x, function(){console.log('so will i');})
x.src = 'http://www.foo.com';
So the problem isn't related directly to Image being a native constructor (since XMLHttpRequest works as expected) - it seems to be something specific to setting img.src. I can only guess it's because setting an src behaves a lot like a method (in that it causes the request to be made). Is there such a thing in JS as a method which can be called like a property?
Assuming it's not that, does anyone know/can guess if this is desired behaviour of Object.observe (couldn't see anything in mdn docs), and if not, where might be the best place for me to report it as a bug?
x.src =
is a sort of shorthand for x.setAttribute('src', ...
, and setting attributes does not trigger Object.observe
--this is the DOM world, not the JS object world. Attributes on HTMLElements are not JS object properties (although sometimes they pretend to be; actually they lurk within the attributes
property as a NamedNodeMap
), and JS object properties are what Object.observe
observes. You can verify this by setting a non-attribute property on your image, and see the observer function firing.
Setting src
on XMLHttpRequest
works because XMLHttpRequest
is just a plain old JS object and src
is just a plain old property on it.
If you want to observe attribute changes, you can use mutation observers.