Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 04.04.2020, 14:29
Новичок на форуме
Отправить личное сообщение для Ekaterina8888 Посмотреть профиль Найти все сообщения от Ekaterina8888
 
Регистрация: 04.04.2020
Сообщений: 3

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


Понимаю, что теряется контекст, но не понимаю, как исправить. Помогите, пожалуйста
Ответить с цитированием
  #2 (permalink)  
Старый 05.04.2020, 07:56
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Вот тут
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>

Последний раз редактировалось voraa, 05.04.2020 в 10:23.
Ответить с цитированием
  #3 (permalink)  
Старый 05.04.2020, 22:33
Новичок на форуме
Отправить личное сообщение для Ekaterina8888 Посмотреть профиль Найти все сообщения от Ekaterina8888
 
Регистрация: 04.04.2020
Сообщений: 3

Огромное спасибо!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при изменении input дочернего окна KolaKola Общие вопросы Javascript 10 28.11.2017 15:42
событие, которое срабатывает при изменении DOM структуры amigo* Events/DOM/Window 30 11.04.2017 13:39
Ошибка при загрузке файла: Error: EISDIR: illegal operation on a directory, open Sigizmund2012 Node.JS 2 31.10.2015 13:01
Не та кодировка при изменении элементов DOM, загружаемых через ajax ShootNik Серверные языки и технологии 16 14.10.2010 09:55