Proxy объекта DOM: ошибка Illegal invocation при изменении style
Добрый день!
Есть функция, создающая proxy: function watchObj(node, callback){ return new Proxy(node, { set (target, name, value){ target[name] = value; callback(name, value); return true; } }); } let div = document.createElement('div'); document.body.appendChild(div); let cleverDiv = watchObj(div, function(prop, val){ console.log(prop, val); }); При измении свойства самого объекта (innerHTML) все работает корректно: cleverDiv.innerHTML = '<strong>HTML</strong><em>Changed</em>'; // в консоли innerHTML <strong>HTML</strong><em>Changed</em> При измении свойства внутреннего объекта Style - ошибка: cleverDiv.style.color = 'red'; // Uncaught TypeError: Illegal invocation Понимаю, что теряется контекст, но не понимаю, как исправить. Помогите, пожалуйста |
Вот тут
cleverDiv.style.color = 'red'; Вы не присваиваете в свойство style, а берете его. Значит нужен обработчик get Свойства объектов DOM это не просто строки или числа. Они реализованы через внутренние гетеры и сетеры. Поэтому для них не всегда срабатывает правило, что если обработчик не задан, то просто берется свойство объекта. <!DOCTYPE html> <html> <head> <script> function watchObj(node, callback){ return new Proxy(node, { set (target, name, value){ target[name] = value; callback(name, value); return true; }, get(target, name) { if (!(name in target)) { return undefined; } const value = target[name]; return typeof value == "function" ? (...args) => value.apply(target, args) : value; } }); } document.addEventListener('DOMContentLoaded', () => { let div = document.createElement('div'); document.body.appendChild(div); let cleverDiv = watchObj(div, function(prop, val){ console.log(prop, val); }); cleverDiv.innerHTML = '<strong>HTML</strong><em>Changed</em>'; cleverDiv.style.color = 'red'; let span = document.createElement('span'); span.textContent = ' appended'; cleverDiv.appendChild(span); }) </script> </head> <body> </body> </html> |
Огромное спасибо!
|
Часовой пояс GMT +3, время: 11:24. |