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'
Другие вопросы по тегам