Как установить css свойство для состояния :hover на JS/Jquery?
Это будет работать даже, если был установлен параметр hover в CSS у данного элемента.
Отслеживать
51.6k 201 201 золотой знак 63 63 серебряных знака 245 245 бронзовых знаков
ответ дан 22 фев 2020 в 12:09
Denis640Kb Denis640Kb
14.1k 5 5 золотых знаков 22 22 серебряных знака 46 46 бронзовых знаков
То же самое на Jquery. var elem = document.getElementById(‘opacity’); elem.mouseover(function()< elem.css("opacity", 0.6); >) elem.mouseleave(function () < elem.css("opacity", 1); >) еще не разобрался с этим вашим форматированием. Спасибо за ответ.
23 фев 2020 в 9:02
Если чистый JS то это сюда смотреть Если с использованием библиотеки jQuery то метод hover
Отслеживать
ответ дан 22 фев 2020 в 11:49
BlackStar1991 BlackStar1991
5,856 3 3 золотых знака 21 21 серебряный знак 60 60 бронзовых знаков
- javascript
- css
- hover
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Состояние компонента
Метод setState() планирует изменение объекта состояния ( state ) компонента. Когда состояние меняется, компонент рендерится повторно.
Какая разница между state и props ?
props (намеренно сокращённо от англ. «properties» — свойства) и state — это обычные JavaScript-объекты. Несмотря на то, что оба содержат информацию, которая влияет на то, что увидим после рендера, есть существенное различие: props передаётся в компонент (служат как параметры функции), в то время как state находится внутри компонента (по аналогии с переменными, которые объявлены внутри функции).
Несколько полезных ресурсов для дальнейшего изучения, в каких случаях использовать props , а в каких — state :
- Props vs. State
- ReactJS: Props vs State
Почему setState даёт неверное значение?
В React как this.props , так и this.state представляют значения, которые уже были отрендерены, например, то, что видите на экране.
Вызовы setState являются асинхронными, поэтому не стоит рассчитывать, что this.state отобразит новое значение мгновенно после вызова setState . Необходимо добавить функцию, которая сработает только после обновления состояния, если нужно получить новое значение, основанное на текущем состоянии (ниже подробный пример).
Пример кода, который не будет работать так, как ожидаем:
incrementCount() // Примечание: это *не* сработает, как ожидалось. this.setState(count: this.state.count + 1>); > handleSomething() // Допустим, что `this.state.count` начинается с 0. this.incrementCount(); this.incrementCount(); this.incrementCount(); // Когда React делает последующий рендер компонента, `this.state.count` будет 1, хотя мы ожидаем 3. // Так происходит, потому что функция `incrementCount()` берёт своё значение из `this.state.count`, // но React не обновляет `this.state.count`, пока компонент не отрендерится снова. // Получается, что `incrementCount()` обращается к текущему значению `this.state.count`, а это 0 каждый раз, и добавляет 1. // Как исправить это — разберём ниже! >
Далее перейдём к исправлению указанной проблемы.
Как обновить состояние значениями, которые зависят от текущего состояния?
Нужно добавить функцию вместо объекта к setState , которая будет срабатывать только на самой последней версии состояния (пример ниже).
В чём разница между добавлением объекта или функции к setState ?
Добавление функции даёт вам доступ к текущему состоянию внутри самой функции. Так как setState вызовы «сгруппированы», это помогает связать изменения и гарантирует, что они будут выполняться друг за другом, а не конфликтовать.
incrementCount() this.setState((state) => // Важно: используем `state` вместо `this.state` при обновлении. return count: state.count + 1> >); > handleSomething() // Возьмём снова для примера, что `this.state.count` начинается с 0. this.incrementCount(); this.incrementCount(); this.incrementCount(); // Если посмотреть на значение `this.state.count` сейчас, это будет по-прежнему 0. // Но когда React отрендерит компонент снова, будет уже 3. >
Когда setState работает асинхронно?
В настоящее время setState работает асинхронно внутри обработчиков событий.
Это даёт гарантию, например, когда Родитель и Ребёнок вызывают setState во время клика, Ребёнок не будет рендериться дважды. Вместо этого React «откладывает» обновление состояния в самый конец событий в браузере. Это помогает сильно повысить производительность больших приложений.
Но не стоит полностью полагаться на такое поведение. В будущих версиях React будет использовать отложенные обновления состояния по умолчанию не только в обработчиках событий.
Почему React не обновляет this.state синхронно?
Как говорилось ранее, React намеренно «ждёт» пока все компоненты вызовут setState() в своих обработчиках событий прежде чем начать повторный рендер. Это избавляет от ненужных повторных рендеров.
Вы можете задаваться вопросом: почему React не может просто сразу обновить this.state без повторного рендеринга?
На это есть две причины:
- Это нарушит логику работы props и state , а значит станет причиной многих багов, которые будет сложно исправить.
- Это сделало бы невозможным реализацию некоторых возможностей, над которыми мы сейчас работаем.
Этот GitHub-комментарий рассматривает конкретные примеры, которые помогут глубже изучить этот вопрос.
Стоит ли использовать такие библиотеки, как Redux или MobX?
Но вообще будет здорово сначала изучить React, прежде чем переходить к библиотекам. Можно создать готовое рабочее приложение, используя только React.
:hover, :focus, :active, или зачем указывать состояния элементам
CSS-псевдоклассы :hover , :focus и :active задают элементам состояния, которые реализуются при определённых действиях пользователя. Состояния меняют цвет или размер элемента, добавляют ему рамку, делают более интерактивным, выделяют и указывают на его назначение.
В статье рассмотрим, в чём различия состояний, какие элементы важно выделять и как это влияет на доступность сайта.
Основные состояния интерактивных элементов
:hover
Состояние :hover срабатывает, когда пользователь наводит курсор на элемент. Часто используется для создания эффекта взаимодействия с элементом, например, при наведении на ссылку меняется цвет текста. Это даёт пользователю понять, что на элемент можно нажать и получить определённый результат.
.link < color: #000000; >.link:hover
:focus
Состояние :focus срабатывает при клике на элемент или переходе на него с клавиатуры при помощи клавиши tab . Применяется состояния ко всем интерактивным элементам — , , , и элементам с tabindex .
Существует также состояние :focus-visible , которое возникает исключительно при фокусе с клавиатуры. Это состояние улучшает доступность сайта для пользователей с ограниченными возможностями. Если человек перемещается по интерфейсу с помощью клавиатуры, ему важно понимать, где он находится. Поэтому состояние фокуса рекомендуется делать как можно более заметным.
.link < color: #000000; >.link:focus
:active
Состояние :active срабатывает, когда пользователь взаимодействует с элементом, например, когда удерживает кнопку мыши на элементе. Часто используется для создания эффекта «нажатия» на кнопку или ссылку. :active может не сильно отличаться по цвету, так как пользователь знает, с каким элементом взаимодействует.
.link < color: #000000; >.link:active
Как состояния влияют на доступность сайта
Не все пользователи используют мышь, поэтому важно, чтобы по сайту можно было перемещаться при помощи клавиатуры или других альтернативных устройств.
Рекомендуется обязательно указывать состояния :hover , :focus и :active для всех интерактивных элементов, с которыми взаимодействует пользователь. Это позволяет создать доступный и понятный интерфейс.
В формах обратной связи состояние :focus используется для выделения активного поля при навигации с помощью клавиатуры. Это помогает пользователям с ограниченными возможностями корректно заполнять форму.

Когда состояния элементов различаются, пользователю легко понять, где ссылка, а где сейчас находится фокус. Ссылкам лучше указывать разные цвета для :hover и :active , чтобы пользователь мог отличить, какой элемент он выбрал.
Поэтому прописывать все состояния вместе не всегда хорошая идея:
.a:hover, .a:focus, .a:active
Кроме того, в разных браузерах и операционных системах отображение состояний может отличаться, поэтому такой код не будет работать идеально. Лучше полностью разделять состояния и каждому давать свою стилизацию.
.a:hover <> .a:focus <> .a:active <>
Также состояния элементов могут использоваться для создания эффектов анимации и визуальных изменений на сайте. Например, при наведении на изображение можно увеличить его размер или добавить эффект тени.
Узнать больше о доступности сайтов и способах её улучшения вы можете на нашем специализированном курсе.
Материалы по теме
- CSS-селекторы. Шпаргалка для новичков
- Как убрать подчёркивание ссылок
- Как сделать всплывающую подсказку
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Читать дальше

Новое в 2023 — text-wrap: balance
В 2023 в CSS появилось любопытное свойство text-wrap со значением balance . Оно «уравновешивает» текстовые элементы, чтобы они приятнее выравнивались внутри блока.
Ограничение — текст не длиннее 6 строк, иначе браузеру придётся непросто, и лучше не применять это свойство к body .
Вот пример заголовка c text-wrap: balance и без него.
На момент написания заметки свойство поддерживается во всех больших браузерах, кроме Safari, а на мобильных — только в Chrome, но то ли ещё будет.
- 13 ноября 2023

Знакомство с CSS
После того как мы разобрались с базовой структурой веб-страницы с помощью HTML, пришло время привнести в неё стиль и красоту. В этом нам поможет CSS, что означает Cascading Style Sheets, или «каскадные таблицы стилей».
CSS используется для оформления HTML-страниц. Если HTML — это скелет сайта, то CSS — его одежда. С помощью CSS мы можем задавать цвета, шрифты, отступы, добавлять анимации и многое другое.
- 1 ноября 2023

Увеличение ссылки при наведении
Задача: плавно увеличить ссылку при наведении.
Решение:
a < display: inline-block; transition: transform 0.3s ease; >a:hover
Первые два свойства просто немного меняют вид ссылки. Свойство color: maroon; меняет цвет текста в тегах на темно-красный, а свойство text-decoration : none; убирает подчеркивание.
Но наша задача — плавно увеличить размер ссылки, а не просто её перекрасить. Поэтому используем свойство transform: scale(1.2) , которое срабатывает при наведении курсора и увеличивает размер ссылки в 1.2 раза по сравнению с её начальным размером.
- 13 октября 2023

WOFF больше не нужен
Я купил и скачал шрифты для недавнего проекта, распаковал папку, где были только WOFF2-файлы, и сначала не поверил, что такое бывает.
Потом мне стало интересно: они что, забыли WOFF? А он вообще ещё нужен? Ну, всё-таки, веб — это место, где постоянно всё меняется и улучшается, поэтому я пошёл и спросил людей в Mastodon. Ответ был единодушным: нужен только WOFF2!
Я хорошо помню пост от Зака в конце 2016, после которого я отказался от исчерпывающего синтаксиса @font-face , включавшего, вдобавок, TTF, EOT и SVG-шрифты, и перешёл только на WOFF2 и WOFF.
Похоже, с тех пор мир веб-шрифтов изменился ещё разок, и вот актуальная версия @font-face :
@font-face
Остался всего один формат. Просто, скажите?
Как писал Зак, «так как в вебе, когда шрифт не найден, всё равно подгружаются системные шрифты, мы можем идти в ногу со временем». Итак, какие браузеры отправятся в тёмные века системных шрифтов с этим синтаксисом?
- IE 11, 10, 9, 8, 7, …
- Chrome 4–35
- Edge 12 и 13
- Safari 3–9.1
- Firefox 2–38
- Opera 22 и ниже
- Android 4.4.4 KitKat и ниже (а это
- Safari на iOS 3.2–9.3
Caniuse.com показывает, что почти у 95% пользователей есть браузер с поддержкой WOFF2. А в относительной статистике (Date Relative — прим. перев.) заметно, что массовый переход на WOFF2 случился в 2015 и 2016. К концу 2016 во всех последних версиях больших браузеров появилась поддержка WOFF2.3
А спустя 7 лет поддержка расширилась настолько, что можно уже не добавлять в проект WOFF-файлы — ну, кроме случая, когда вы точно знаете, что много ваших пользователей используют старые устройства и браузеры.
С другой стороны, нет смысла и удалять WOFF из старых проектов. Если вы подключали WOFF2 раньше WOFF внутри @font-face — и порядок здесь важен — то браузер просто скачает и подключит WOFF2-версию.
И если однажды вы, как и я, обнаружите себя перед папкой, полной файлов WOFF2, знайте, что WOFF — уже всё.
- 23 сентября 2023

Трясём пароль с помощью CSS
Знаете момент, когда всё на сайте уже сделано, и хочется добавить какую-нибудь маленькую незаметную фишку? Мы тоже знаем, поэтому давайте просто потрясём поле пароля, когда пользователь ввёл неверный пароль. Как на Маке.
Вот что получится в итоге:
- 7 сентября 2023

Как сделать тёмную тему на сайте
Без лишних слов создадим простой переключатель для светлой и темной темы с использованием HTML, CSS и JavaScript. Нам понадобятся три файла — index.html , styles.css и script.js .
HTML
Основная разметка страницы — заголовок, абзац текста, список и текст в рамке.
CSS (styles.css):
Здесь задаём цвета для светлой и тёмной темы, а ещё минимальную стилизацию текста и блока с рамкой.
body < font-family: Arial, sans-serif; transition: background-color 0.3s ease; >body.light-theme < background-color: #ffffff; color: #000000; >body.dark-theme < background-color: #121212; color: #ffffff; >.boxed-text
JavaScript (script.js)
Этот код нужен, чтобы переключать тему при нажатии на кнопку:
document.getElementById('themeToggle').addEventListener('click', function() < const currentTheme = document.body.className; if (currentTheme === 'light-theme') < document.body.className = 'dark-theme'; >else < document.body.className = 'light-theme'; >>);
При загрузке страницы по умолчанию будет установлена светлая тема. При нажатии на кнопку «Переключить тему» будет происходить переключение между светлой и темной темой.
- 29 августа 2023

4 способа центрировать текст в CSS
Центрирование элементов на веб-странице — это одна из наиболее распространенных задач, с которой мы сталкиваемся при работе с макетами. И хотя центрирование текста по горизонтали довольно простое ( text-align: center; и делов-то), вертикальное центрирование может быть немного сложнее. Давайте рассмотрим несколько методов.
Метод 1: Flexbox
Flexbox — это один из самых простых и эффективных способов центрирования.
Заворачиваем текст в с классом center-both :
Центрированный текст
.center-both
Метод 2: CSS Grid
HTML такой же, как в предыдущем примере. В CSS включаем гриды и используем свойство place-items со значением center :
.center-both
Метод 3: позиционирование и Transform
Этот метод немного старомодный и работает не идеально. Здесь у div устанавливается relative позиция. А
внутри дива мы сдвигаем с помощью абсолютного позиционирования. Не слишком элегантно:
.center-both < position: relative; >.center-both p
HTML остается таким же. Вот что получается:
Плохой метод: использование line-height
Если у вас однострочный текст, вы можете установить line-height , равный высоте родительского элемента.
.center-both < line-height: 200px; /* Пример высоты */ text-align: center; >
Этот метод не подойдет для многострочного текста. Да и вообще мы очень не рекомендуем так делать, это прям совсем для любителей острых ощущений. Потому что вот:
Если вам интересно узнать больше о каждом из этих методов, рекомендуем посмотреть документацию по Flexbox на MDN или документацию по CSS Grid на MDN, а ещё пройти курсы в HTML Academy.
- 28 августа 2023

Как скруглить рамку. CSS-свойство border-radius
CSS-свойство border-radius помогает скруглить углы элемента. Оно особенно полезно для стилизации кнопок, форм, карточек товаров и других элементов сайта.
- 28 июля 2023

CSS-свойство contain
Представьте, что у вас есть контейнер. Внутри него находятся разные элементы: текст, изображения или что-то другое. Свойство contain говорит браузеру, как именно элементы должны взаимодействовать. Например, они могут быть ограничены, влиять на расположение друг друга или менять свои размеры.
Также свойство помогает повысить производительность страницы. Например, браузер понимает, когда при изменении свойств элемента нужно перерисовать страницу, а когда нет.
⭐ CSS-свойство contain определяет, как элемент должен взаимодействовать с другими элементами внутри контейнера.
Синтаксис
.container
- 14 июля 2023

Как задать позицию и размер элемента. CSS-свойство inset
CSS-свойство inset задаёт позицию и размер элемента на странице. Это комбинация четырёх отдельных свойств: top , right , bottom и left , которые определяют отступы от верхнего, правого, нижнего и левого края элемента.
Синтаксис
.element
- 13 июля 2023
Позиционирование элементов с помощью JS
CSS отлично справляется с позиционированием элементов, но иногда его не хватает. Учимся выбирать, когда нужен CSS, а когда — JS.
Время чтения: 11 мин
Открыть/закрыть навигацию по статье
- Кратко
- Когда использовать стили
- Когда использовать скрипты
- Как менять позиционирование на скриптах
- Изменять классы
- Изменять style
- Изменение margin или top / left / right / bottom
- Изменение transform
- Изменение кастомных свойств CSS
- Саша Беспоясов советует
Контрибьюторы:
Обновлено 16 ноября 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
Элементы на странице можно позиционировать не только с помощью стилей, но и с помощью JavaScript. В этой статье мы рассмотрим ситуации, когда это оправдано и как таким позиционированием пользоваться.
Прежде чем мы приступим к непосредственно позиционированию, давайте определимся, зачем нам ещё один способ расставлять элементы, когда у нас уже есть CSS.
Когда использовать стили
Скопировать ссылку «Когда использовать стили» Скопировано
Используйте стили для позиционирования всегда, когда это возможно.
CSS — это инструмент, который специально был придуман для стилизации документов.
- Это работает в среднем быстрее.
- Это не собьёт с толку других разработчиков, которые будут читать ваш код.
- Это разделяет зоны ответственности между скриптами и стилями.
Когда использовать скрипты
Скопировать ссылку «Когда использовать скрипты» Скопировано
Используйте скрипты для позиционирования тогда, когда стилей не хватает.
CSS ограничен в обратной связи на действия пользователей на экране. В нём есть такие штуки как @keyframes , transition , :hover , :active , :focus и т. д., но этого не всегда достаточно.
Иногда нужно, чтобы в ответ на действия пользователя на странице происходили сложные преобразования или чтобы пользователи сами могли управлять анимациями на странице.
Такие случаи — это не просто стилизация документа, а скорее смесь из стилизации и программной логики. Чтобы решить такую задачу, нам нужны как инструменты стилизации (CSS), так и инструменты для программирования логики (JS).
Как менять позиционирование на скриптах
Скопировать ссылку «Как менять позиционирование на скриптах» Скопировано
Изменять положение элементов (как и любые стили элементов) на странице можно несколькими способами.
Изменять классы
Скопировать ссылку «Изменять классы» Скопировано
Допустим, мы хотим переместить элемент при клике на него в другое место. Для решения такой задачи нам вполне подойдёт способ с изменением класса у элемента.
.element /* Стили самого элемента. */> .element-initial /* Стили, определяющие начальное положение элемента на странице, например: */ transform: translateX(0px);> .element-final /* Стили, определяющие конечное положение, например: */ transform: translateX(50px);>.element /* Стили самого элемента. */ > .element-initial /* Стили, определяющие начальное положение элемента на странице, например: */ transform: translateX(0px); > .element-final /* Стили, определяющие конечное положение, например: */ transform: translateX(50px); >Элементу изначально заданы классы element element — initial , которые задают его стили, а также его начальное положение.
Теперь в ответ на действие пользователя (например, в ответ на клик), поменяем класс элемента, отвечающий за положение. Воспользуемся методом class List . toggle ( ) у элемента, чтобы добавить класс, если его нет на элементе, и убрать, если класс есть:
// Обрабатываем событие клика на элементе:element.addEventListener('click', () => element.classList.toggle('element-final') element.classList.toggle('element-initial')>)// Обрабатываем событие клика на элементе: element.addEventListener('click', () => element.classList.toggle('element-final') element.classList.toggle('element-initial') >)Тогда получим элемент, который меняет своё положение при клике на него:
Этот способ изменять стили элемента с помощью скриптов самый простой и чистый — все стили остаются описанными внутри CSS. Однако он не всегда подходит.
Использовать такой способ можно, когда мы заранее знаем, куда и откуда мы хотим переместить элемент, но не знаем момент, когда нам это понадобится.
Изменять style
Скопировать ссылку «Изменять style» Скопировано
Второй способ изменять положение элемента — менять атрибут style с помощью JS.
При работе со style следует помнить, что у этого атрибута высокая специфичность, из-за чего он будет перебивать основные стили элемента. Его следует использовать с осторожностью.
Он подойдёт в случае, когда мы мгновенно хотим отражать изменения на элементе, даже если не знаем, что и когда поменяется. Например, если мы хотим перемещать элемент мышкой на экране, нам может понадобиться менять его style .
Для изменения положения через style можно использовать разные свойства.
Изменение margin или top / left / right / bottom
Скопировать ссылку «Изменение margin или top / left / right / bottom» Скопировано
Первое, что приходит на ум — изменение соответствующих CSS-свойств типа margin или left / top / right / bottom .
Создадим элемент с классом element :
.element width: 50px; height: 50px; background: black; position: absolute;>.element width: 50px; height: 50px; background: black; position: absolute; >Теперь попробуем написать драг-н-дроп для мыши.
// Сперва создадим ссылку на этот элемент,// чтобы обрабатывать события на нём:const element = document.querySelector('.element') // Переменная dragging будет отвечать за состояние элемента.// Если его тащат, то переменная будет со значением true.// По умолчанию она false.let dragging = false // В переменных startX и startY мы будем держать координаты точки,// в которой находился элемент, когда мы начали его тащить мышью.let startX = 0let startY = 0 // При событии mousedown (когда на элемент нажимают мышью)// мы отмечаем dragging как true — значит, элемент начали тащить.element.addEventListener('mousedown', (e) => dragging = true // В значения для startX и startY мы помещаем положение курсора // через свойства события e.pageX и e.pageY. startX = e.pageX - Number.parseInt(element.style.left || 0) startY = e.pageY - Number.parseInt(element.style.top || 0) // Из положения курсора мы вычитаем отступы элемента, если они есть. // Вычитание отступов нам нужно, чтобы элемент «запоминал» // своё последнее положение, иначе мы всегда будем начинать тащить его // от начала экрана.>) // Далее мы обрабатываем событие перемещения мыши по body.// Мы наблюдаем именно за body, потому что хотим,// чтобы изменения работали на всей странице,// а не только внутри элемента element.document.body.addEventListener('mousemove', (e) => // Если элемент не тащат, то ничего не делаем. if (!dragging) return // Если тащат, то высчитываем новое положение, // вычитая начальное положение элемента из положения курсора. element.style.top = `$px` element.style.left = `$px`>) // Когда мы отпускаем мышь, мы отмечаем dragging как false.document.body.addEventListener('mouseup', () => dragging = false>)// Сперва создадим ссылку на этот элемент, // чтобы обрабатывать события на нём: const element = document.querySelector('.element') // Переменная dragging будет отвечать за состояние элемента. // Если его тащат, то переменная будет со значением true. // По умолчанию она false. let dragging = false // В переменных startX и startY мы будем держать координаты точки, // в которой находился элемент, когда мы начали его тащить мышью. let startX = 0 let startY = 0 // При событии mousedown (когда на элемент нажимают мышью) // мы отмечаем dragging как true — значит, элемент начали тащить. element.addEventListener('mousedown', (e) => dragging = true // В значения для startX и startY мы помещаем положение курсора // через свойства события e.pageX и e.pageY. startX = e.pageX - Number.parseInt(element.style.left || 0) startY = e.pageY - Number.parseInt(element.style.top || 0) // Из положения курсора мы вычитаем отступы элемента, если они есть. // Вычитание отступов нам нужно, чтобы элемент «запоминал» // своё последнее положение, иначе мы всегда будем начинать тащить его // от начала экрана. >) // Далее мы обрабатываем событие перемещения мыши по body. // Мы наблюдаем именно за body, потому что хотим, // чтобы изменения работали на всей странице, // а не только внутри элемента element. document.body.addEventListener('mousemove', (e) => // Если элемент не тащат, то ничего не делаем. if (!dragging) return // Если тащат, то высчитываем новое положение, // вычитая начальное положение элемента из положения курсора. element.style.top = `$e.pageY - startY>px` element.style.left = `$e.pageX - startX>px` >) // Когда мы отпускаем мышь, мы отмечаем dragging как false. document.body.addEventListener('mouseup', () => dragging = false >)Тогда получится вот такой драг-н-дроп:
Это работает, но не очень эффективно, потому что изменения в этих свойствах заставляют браузер делать много лишней работы.
Мы можем сделать лучше.
Изменение transform
Скопировать ссылку «Изменение transform» Скопировано
Перепишем наш драг-н-дроп, меняя теперь значение свойства transform .
Основа кода останется той же, стили и разметка не поменяются вовсе. В скриптах мы слегка изменим определение положения элемента.
// . element.addEventListener('mousedown', (e) => dragging = true // В этот раз мы не сможем считать нужные нам значения напрямую. // Вместо этого нам потребуется вначале вычислить стиль элемента // через window.getComputedStyle(), а затем узнать значение // свойства transform. const style = window.getComputedStyle(element) // Мы могли бы просто считать значение style.transform, // но это бы нам не сильно помогло. // При обычном считывании мы бы получили нечто вроде: // matrix(1, 0, 0, 1, 27, 15); // // Это матрица афинных преобразований. // Её можно представить в виде: // matrix(scaleX, skewY, skewX, scaleY, translateX, translateY); // где: // - scaleX — масштабирование по горизонтали, // - scaleY — масштабирование по вертикали, // - skewX — перекос по горизонтали, // - skewY — перекос по вертикали, // - translateX — смещение по горизонтали, // - translateY — смещение по вертикали. // // Но даже учитывая, что у нас есть все необходимые числа, // работать с этим неудобно — это же просто строка. // // К счастью мы можем воспользоваться DOMMatrixReadOnly, // который преобразует эту матрицу в удобную для использования: const transform = new DOMMatrixReadOnly(style.transform) // Теперь мы можем воспользоваться свойствами, // которые содержат в себе значения translateX и translateY. const translateX = transform.m41 const translateY = transform.m42 // Дальше — как раньше, только вычитаем не top и left, // а translateX и translateY. startX = e.pageX - translateX startY = e.pageY - translateY>)// добавляем возможность отпустить элемент при отжатии клавишиdocument.body.addEventListener("mouseup", () => dragging = false;>);// . element.addEventListener('mousedown', (e) => dragging = true // В этот раз мы не сможем считать нужные нам значения напрямую. // Вместо этого нам потребуется вначале вычислить стиль элемента // через window.getComputedStyle(), а затем узнать значение // свойства transform. const style = window.getComputedStyle(element) // Мы могли бы просто считать значение style.transform, // но это бы нам не сильно помогло. // При обычном считывании мы бы получили нечто вроде: // matrix(1, 0, 0, 1, 27, 15); // // Это матрица афинных преобразований. // Её можно представить в виде: // matrix(scaleX, skewY, skewX, scaleY, translateX, translateY); // где: // - scaleX — масштабирование по горизонтали, // - scaleY — масштабирование по вертикали, // - skewX — перекос по горизонтали, // - skewY — перекос по вертикали, // - translateX — смещение по горизонтали, // - translateY — смещение по вертикали. // // Но даже учитывая, что у нас есть все необходимые числа, // работать с этим неудобно — это же просто строка. // // К счастью мы можем воспользоваться DOMMatrixReadOnly, // который преобразует эту матрицу в удобную для использования: const transform = new DOMMatrixReadOnly(style.transform) // Теперь мы можем воспользоваться свойствами, // которые содержат в себе значения translateX и translateY. const translateX = transform.m41 const translateY = transform.m42 // Дальше — как раньше, только вычитаем не top и left, // а translateX и translateY. startX = e.pageX - translateX startY = e.pageY - translateY >) // добавляем возможность отпустить элемент при отжатии клавиши document.body.addEventListener("mouseup", () => dragging = false; >);А также немного обновим изменение положения:
// . document.body.addEventListener('mousemove', (e) => if (!dragging) return const x = e.pageX - startX const y = e.pageY - startY // В этот раз мы можем объединить обновлённые координаты // в одну запись translate, которую потом // присвоим в качестве значения свойству transform. element.style.transform = `translate($px, $px)`>)// . document.body.addEventListener('mousemove', (e) => if (!dragging) return const x = e.pageX - startX const y = e.pageY - startY // В этот раз мы можем объединить обновлённые координаты // в одну запись translate, которую потом // присвоим в качестве значения свойству transform. element.style.transform = `translate($x>px, $y>px)` >)В итоге получим такой же драг-н-дроп, но работающий на transform .
Но мы можем ещё лучше
Изменение кастомных свойств CSS
Скопировать ссылку «Изменение кастомных свойств CSS» Скопировано
Сейчас код рабочий, но его трудно читать. Как минимум потому, что надо знать, как работает матрица преобразований и DOM Matrix Read Only .
Мы же можем не менять значение transform вовсе, а вместо этого менять значение CSS-переменных, чтобы обновлять положение элемента!
Первым делом определяем кастомные свойства CSS в стилях элемента:
.element width: 50px; height: 50px; background: black; position: absolute; /* В переменной --x мы будем держать значение координаты по горизонтали; в переменной --y — по вертикали. */ --x: 0px; --y: 0px; /* Укажем transform, значением которого передадим translate с указанными переменными. В итоге нам не придётся менять сам transform, мы сможем ограничиться лишь изменением значений переменных --x и --y. */ transform: translate(var(--x), var(--y));>.element width: 50px; height: 50px; background: black; position: absolute; /* В переменной --x мы будем держать значение координаты по горизонтали; в переменной --y — по вертикали. */ --x: 0px; --y: 0px; /* Укажем transform, значением которого передадим translate с указанными переменными. В итоге нам не придётся менять сам transform, мы сможем ограничиться лишь изменением значений переменных --x и --y. */ transform: translate(var(--x), var(--y)); >Теперь подправим скрипт, чтобы сперва считать значение этих переменных:
// . element.addEventListener('mousedown', (e) => dragging = true // Получаем стиль элемента: const style = window.getComputedStyle(element) // Считываем значение каждой переменной через getPropertyValue: const translateX = parseInt(style.getPropertyValue('--x')) const translateY = parseInt(style.getPropertyValue('--y')) // Дальше всё остаётся по-старому :–) startX = e.pageX - translateX startY = e.pageY - translateY>)// . element.addEventListener('mousedown', (e) => dragging = true // Получаем стиль элемента: const style = window.getComputedStyle(element) // Считываем значение каждой переменной через getPropertyValue: const translateX = parseInt(style.getPropertyValue('--x')) const translateY = parseInt(style.getPropertyValue('--y')) // Дальше всё остаётся по-старому :–) startX = e.pageX - translateX startY = e.pageY - translateY >)А теперь изменим обновление стилей:
// . document.body.addEventListener('mousemove', (e) => if (!dragging) return // Обратите внимание, насколько лаконичной стала запись. // Мы всего лишь указываем, какое значение должна // принять каждая из переменных: element.style.setProperty("--x", `$px`) element.style.setProperty("--y", `$px`)>)// . document.body.addEventListener('mousemove', (e) => if (!dragging) return // Обратите внимание, насколько лаконичной стала запись. // Мы всего лишь указываем, какое значение должна // принять каждая из переменных: element.style.setProperty("--x", `$e.pageX - startX>px`) element.style.setProperty("--y", `$e.pageY - startY>px`) >)В результате получаем такой же драг-н-дроп!
На практике
Скопировать ссылку «На практике» Скопировано