Object.observe() не работает с родным объектом Image
Это не работает (в Chrome 39 на 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);
Но это будет:
var x = new function nonNative(){};
Object.observe(x, function(){console.log('i will run');})
x.src = 'http://www.foo.com';
И так будет это:
var x = new XMLHttpRequest();
Object.observe(x, function(){console.log('so will i');})
x.src = 'http://www.foo.com';
Таким образом, проблема не связана напрямую с тем, что Image является нативным конструктором (поскольку XMLHttpRequest работает как положено) - похоже, это что-то особенное для установки img.src. Я могу только догадываться, что это потому, что установка src ведет себя очень похоже на метод (в том смысле, что это вызывает выполнение запроса). Есть ли такая вещь в JS как метод, который можно вызвать как свойство?
Предполагая, что это не так, кто-нибудь знает / может догадаться, является ли это желаемым поведением Object.observe (ничего не видно в mdn docs), и если нет, где мне лучше всего сообщить об этом как об ошибке?
2 ответа
x.src =
это своего рода сокращение для x.setAttribute('src', ...
и установка атрибутов не срабатывает Object.observe
- это мир DOM, а не объектный мир JS. Атрибуты в элементах HTMLE не являются свойствами объекта JS (хотя иногда они притворяются; на самом деле они скрываются внутри attributes
собственность как NamedNodeMap
), а свойства объекта JS - это то, что Object.observe
наблюдает. Вы можете убедиться в этом, установив свойство без атрибутов на вашем изображении и увидев срабатывание функции наблюдателя.
настройка src
на XMLHttpRequest
работает потому что XMLHttpRequest
это просто старый объект JS и src
это просто старая собственность на нем.
Если вы хотите наблюдать изменения атрибутов, вы можете использовать наблюдатели мутаций.
Как уже упоминали другие, src
это не атрибут, это определенная пара getter/setter, поэтому, присваивая его, вы фактически вызываете функцию.
Поскольку это элемент DOM, вам лучше использовать MutationObserver
,
var x = new Image();
var observer = new MutationObserver(function(){
console.log('i will run');
});
observer.observe(x, {attributes: true});
x.src = 'http://www.example.com.com'