Не пойму работу Object.assign() для documentElement?
В общем задача такая: надо чтобы при движении курсора по экрану - для определённого элемента в CSS-свойство transform: rotate подставлялись координаты движения мыши, и типо ты двигаешь курсор по экрану - и этот элемент наклоняется.
// 1й вар document.addEventListener('mousemove', e => { Object.assign(document.documentElement, { style: ` --move-x: ${(e.clientX - window.innerWidth / 2) * -.005}deg; --move-y: ${(e.clientY - window.innerHeight / 2) * .01}deg; ` }) }) //2й вар document.addEventListener('mousemove', e => { let moveX = (e.clientX - window.innerWidth / 2) * (-.005) + 'deg'; let moveY = (e.clientY - window.innerHeight / 2) * .01 + 'deg'; document.querySelector('.layers__container').style.transform = `rotateX(${moveY})` document.querySelector('.layers__container').style.transform = `rotateY(${moveX})` }) |
// 1й вар document.addEventListener('mousemove', e => { Object.assign(document.documentElement, { style: ` --move-x: ${(e.clientX - window.innerWidth / 2) * -.005}deg; --move-y: ${(e.clientY - window.innerHeight / 2) * .01}deg; ` }) }) //2й вар document.addEventListener('mousemove', e => { let moveX = (e.clientX - window.innerWidth / 2) * (-.005) + 'deg'; let moveY = (e.clientY - window.innerHeight / 2) * .01 + 'deg'; document.querySelector('.layers__container').style.transform = `rotateX(${moveY})` document.querySelector('.layers__container').style.transform = `rotateY(${moveX})` })
У меня есть два варианта решения. Я не до конца понимаю принцип работы 1го варианта, и не понимаю, почему не работает 2й.
Насчёт 1го: как я понял - мы при движении мыши по экрану, берём documentElement(он же тег html) и через Object.assign - копируем туда Объект, в котором есть Ключ 'style'.
ЧТО Я НЕ ПОНЯЛ: Object.assign - это метод копирования свойств одного Объекта в другой. То бишь
мы берём объект documentElement и копируем в него свойства другого Объекта. И как я думал, по такой логике если вызвать
console.log(Object.entries(document.documentElement)) |
console.log(Object.entries(document.documentElement))
то выведутся все пары ключ+значение, и выведется ключ Style со своим значением. Но его нет.
Но при этом, каким то образом в тег html у нас добавился АТРИБУТ style, в котором уже прописаны его значения из JS.
Если коротко: я не пойму с чего вдруг метод Object.assign инлайново прописал для documentElement АТРИБУТ style. Как он это вообще мог сделать?
А насчёт 2го варианта: он неправильно работает, видимо один
.style.transform
перезаписывает другой, и в общем движение происходит только по одной Оси. Можно как то исправить?
Дополнительно:
> не понимаю, почему не работает 2й.
document.querySelector('.layers__container').style.transform = `rotateX(${moveY})` document.querySelector('.layers__container').style.transform = `rotateY(${moveX})` |
document.querySelector('.layers__container').style.transform = `rotateX(${moveY})` document.querySelector('.layers__container').style.transform = `rotateY(${moveX})`
Потому, что ты перетираешь значение style.transform двумя разными значениями, второе заменяет первое.
> метод Object.assign инлайново прописал для documentElement АТРИБУТ style.
Не совсем, он буквально сделал:
document.documentElement.style.prop1 = "value1";
document.documentElement.style.prop2 = "value2";
Сам он ничего не прописывал, это уже логика работы DOM ноды и ее API.
Просто прочти документацию к Object.assign, лучше в отрыве от DOM API, ибо у DOM API и его объектов есть свои магические методы, геттеры, сеттеры и прочее:
> console.log(Object.entries(document.documentElement)) то выведутся все пары ключ+значение
У "простых" объектов - да, но все сложнее. Если посмотреть MDN описание для Object.entries, то можно увидеть, что он отдает только перечисляемые свойства: An array of strings representing the given object's own enumerable string-keyed property keys.
- сколько нюансов
спасибо за ответ
Ответы:
1) а зачем Object.assign? document.documentElement.style = '--test: 1;' тоже работает, т.к. это прописано в спецификации:
interface mixin ElementCSSInlineStyle { [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; }; |
interface mixin ElementCSSInlineStyle { [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; };
2) просто объединить два выражения в одну через пробел
- насчёт 1го варианта завтра уже посмотрю, а во 2м да, если объединить в одно через пробел - работает, спасибо
Странно что если делать разными выражениями, то не работает как надо. Там же у одного "rotateX" , а у другого "rotateY", поидее мешать друг другу не должны*И ещё интересно, как всё таки Object.assign может прописывать инлайновый Атрибут? У него же другая функция
- Danila232, будут и должны, т.к. это установка свойства, затирающая всё что там было раньше
а element.style = something аналогичен element.style.cssText = something
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос



Метод Object.assign() в JavaScript используется для копирования значений всех перечислимых собственных свойств из одного или нескольких исходных объектов в целевой объект.
Когда вы используете Object.assign() для documentElement, вы пытаетесь скопировать свойства из одного или нескольких объектов в элемент documentElement, который представляет корневой элемент документа (обычно ).
Однако, documentElement является объектом Element, а не обычным JavaScript объектом, поэтому Object.assign() может не работать так, как вы ожидаете. Это связано с тем, что Element объекты включают в себя свойства и методы, специфичные для DOM элементов, которые могут быть не совместимы с методом Object.assign().
Если вам нужно скопировать свойства documentElement, вам лучше использовать другие методы, такие как клонирование элемента или явное копирование свойств.
Например, вы можете клонировать documentElement с помощью метода cloneNode():
const newElement = document.documentElement.cloneNode(true);
Или вы можете явно копировать необходимые свойства:
const newElement = document.createElement('html'); newElement.lang = document.documentElement.lang; newElement.dir = document.documentElement.dir; // Копировать другие свойства по мере необходимости
Таким образом, если у вас возникают проблемы с использованием Object.assign() для documentElement, рекомендуется использовать указанные выше методы для копирования свойств элемента.