Создание изменяемых HTML элементов на чистом JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для того чтобы элемент мог менять свои размеры, создайте специальную ручку, которую будет возможно перетаскивать с места на место, отслеживайте события мыши и меняйте размеры элемента динамически. Вот пример кода:
const elem = document.getElementById('resizable');
elem.style.position = 'relative';
const handle = document.createElement('div');
Object.assign(handle.style, { width: '8px', height: '8px', background: 'blue', position: 'absolute', right: '0', bottom: '0', cursor: 'nwse-resize' });
elem.append(handle);
handle.addEventListener('mousedown', e => {
e.preventDefault();
const startX = e.pageX, startY = e.pageY;
const startWidth = parseInt(window.getComputedStyle(elem).width, 10);
const startHeight = parseInt(window.getComputedStyle(elem).height, 10);
const doDrag = (e) => {
elem.style.width = `${startWidth + e.pageX – startX}px`;
elem.style.height = `${startHeight + e.pageY – startY}px`;
};
const stopDrag = () => {
document.documentElement.removeEventListener('mousemove', doDrag);
document.documentElement.removeEventListener('mouseup', stopDrag);
};
document.documentElement.addEventListener('mousemove', doDrag);
document.documentElement.addEventListener('mouseup', stopDrag);
});
Стоит заметить, что данный способ изменения размеров элемента осуществляется за счёт отслеживания событий мыши непосредственно на document.documentElement
, что позволяет изменять размер элемента, начиная с его нижнего правого угла.
Оптимизация взаимодействия с пользователем
Отзывчивость страницы
Чтобы веб-страница оставалась отзывчивой во время изменения размеров элемента, важно обеспечить плавность всех действий пользователя. В данном случае можно воспользоваться requestAnimationFrame
в обработчике mousemove
для оптимизации обычных операций:
let rafPending = false;
const doDrag = (e) => {
if (rafPending) return;
rafPending = true;
requestAnimationFrame(() => {
elem.style.width = `${startWidth + e.pageX – startX}px`;
elem.style.height = `${startHeight + e.pageY – startY}px`;
rafPending = false;
});
};
Совместимость с различными браузерами
Обязательно проверьте работу кода в разных браузерах, включая Firefox. Для старых версий Internet Explorer (IE <9) подготовьте альтернативные варианты, например, простые уведомления для пользователей этих версий браузера.
Улучшение пользовательского опыта
Внесите изменения в размер и внешний вид ручки, чтобы повысить качество взаимодействия с пользователем. Обновите стиль ручки и добавьте переходные эффекты:
handle.style.transition = 'all 0.2s';
handle.addEventListener('mouseover', () => {
handle.style.background = 'red';
});
handle.addEventListener('mouseout', () => {
handle.style.background = 'blue';
});
Визуализация
Для наглядности сравним процесс изменения размеров элемента с настройкой телескопа:
Телескоп (🔭) – это HTML-элемент
Расширение/Сжатие (🔄) – изменение размера с помощью JavaScript
Окуляр (👁️) – это пункт взаимодействия пользователя с элементом
// Телескоп, настроенный в JavaScript:
element.onmousedown = function(event) {
document.onmousemove = function(moveEvent) {
element.style.width = `${moveEvent.clientX}px`;
element.style.height = `${moveEvent.clientY}px`;
};
document.onmouseup = function() {
document.onmousemove = null;
};
};
Поясним:
До: [🔭👁️] – размер фиксирован
После: [🔭🔄👁️] – размер изменён
Изменение размеров в разных направлениях
Для большей гибкости управления размерами элемента вы можете оборудовать его несколькими ручками:
// Добавляем функцию для создания ручек в разных направлениях
function addResizeHandle(element, position) {
const handle = document.createElement('div');
// Затем применяем необходимые стили и добавляем логику перетаскивания для каждой ручки
element.appendChild(handle);
}
// Укомплектовываем элемент ручками по углам
addResizeHandle(elem, 'top-left');
addResizeHandle(elem, 'top-right');
addResizeHandle(elem, 'bottom-left');
addResizeHandle(elem, 'bottom-right');
Установка ограничений
Установите минимум и максимум для изменения размеров элемента:
// ... в функции doDrag задайте ограничения для новых размеров
elem.style.width = `${newWidth}px`;
elem.style.height = `${newHeight}px`;
Эффективное использование стилей
Сохраните начальные значения стилей и используйте их:
const computedStyle = getComputedStyle(elem);
Используйте computedStyle
для доступа к значениям ширины и высоты в начале операции перетаскивания.
Полезные материалы
- resize – CSS: Cascading Style Sheets — документация о свойстве
resize
в CSS. - Примеры использования resize на CSS-Tricks — полезные советы и примеры.
- HTML DOM Style object — как изменять стили элементов с помощью JavaScript.
- Обработка событий мыши — как работать с событиями мыши в JavaScript.
- Набор JavaScript-утилит — обширный набор JS-утилит для различных задач.
- Как создать плавные CSS-анимации — руководство по созданию плавных CSS-анимаций.