181 lines
5.9 KiB
JavaScript
181 lines
5.9 KiB
JavaScript
/**
|
||
* DOM Utilities
|
||
*
|
||
* Утилиты для работы с DOM: показ/скрытие элементов, работа с классами и т.д.
|
||
*
|
||
* Использование:
|
||
* import { show, hide, toggle } from '{% static "js/utils/domUtils.js" %}';
|
||
*/
|
||
|
||
/**
|
||
* Показывает элемент (удаляет класс d-none)
|
||
*
|
||
* @param {HTMLElement|null} element - элемент для показа
|
||
* @returns {boolean} - true если элемент был скрыт и теперь показан
|
||
*
|
||
* @example
|
||
* show(document.getElementById('myElement'));
|
||
*/
|
||
export function show(element) {
|
||
if (!element) return false;
|
||
const wasHidden = element.classList.contains('d-none');
|
||
element.classList.remove('d-none');
|
||
return wasHidden;
|
||
}
|
||
|
||
/**
|
||
* Скрывает элемент (добавляет класс d-none)
|
||
*
|
||
* @param {HTMLElement|null} element - элемент для скрытия
|
||
* @returns {boolean} - true если элемент был виден и теперь скрыт
|
||
*
|
||
* @example
|
||
* hide(document.getElementById('myElement'));
|
||
*/
|
||
export function hide(element) {
|
||
if (!element) return false;
|
||
const wasVisible = !element.classList.contains('d-none');
|
||
element.classList.add('d-none');
|
||
return wasVisible;
|
||
}
|
||
|
||
/**
|
||
* Переключает видимость элемента (toggle класс d-none)
|
||
*
|
||
* @param {HTMLElement|null} element - элемент для переключения
|
||
* @param {boolean} [force] - принудительно показать (true) или скрыть (false)
|
||
* @returns {boolean} - true если элемент теперь виден, false если скрыт
|
||
*
|
||
* @example
|
||
* toggle(document.getElementById('myElement'));
|
||
* toggle(document.getElementById('myElement'), true); // принудительно показать
|
||
*/
|
||
export function toggle(element, force) {
|
||
if (!element) return false;
|
||
|
||
if (force !== undefined) {
|
||
element.classList.toggle('d-none', !force);
|
||
return force;
|
||
}
|
||
|
||
element.classList.toggle('d-none');
|
||
return !element.classList.contains('d-none');
|
||
}
|
||
|
||
/**
|
||
* Проверяет, виден ли элемент (нет класса d-none)
|
||
*
|
||
* @param {HTMLElement|null} element - элемент для проверки
|
||
* @returns {boolean} - true если элемент виден
|
||
*
|
||
* @example
|
||
* if (isVisible(document.getElementById('myElement'))) {
|
||
* console.log('Элемент виден');
|
||
* }
|
||
*/
|
||
export function isVisible(element) {
|
||
if (!element) return false;
|
||
return !element.classList.contains('d-none');
|
||
}
|
||
|
||
/**
|
||
* Показывает элемент с временной задержкой перед скрытием
|
||
* Полезно для временных уведомлений
|
||
*
|
||
* @param {HTMLElement|null} element - элемент для показа
|
||
* @param {number} [duration=4000] - длительность показа в миллисекундах
|
||
* @returns {number|null} - ID таймера для возможной отмены через clearTimeout
|
||
*
|
||
* @example
|
||
* const timerId = showTemporary(alertElement, 3000);
|
||
* // Отменить автоскрытие: clearTimeout(timerId);
|
||
*/
|
||
export function showTemporary(element, duration = 4000) {
|
||
if (!element) return null;
|
||
|
||
show(element);
|
||
return setTimeout(() => hide(element), duration);
|
||
}
|
||
|
||
/**
|
||
* Добавляет/удаляет класс CSS у элемента
|
||
*
|
||
* @param {HTMLElement|null} element - элемент
|
||
* @param {string} className - имя класса
|
||
* @param {boolean} add - true = добавить, false = удалить
|
||
*
|
||
* @example
|
||
* setClass(element, 'active', true); // добавить класс active
|
||
* setClass(element, 'disabled', false); // удалить класс disabled
|
||
*/
|
||
export function setClass(element, className, add) {
|
||
if (!element) return;
|
||
|
||
if (add) {
|
||
element.classList.add(className);
|
||
} else {
|
||
element.classList.remove(className);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Находит ближайший родительский элемент с указанным селектором
|
||
* Аналог element.closest(), но с дополнительными проверками
|
||
*
|
||
* @param {HTMLElement|null} element - начальный элемент
|
||
* @param {string} selector - CSS селектор
|
||
* @returns {HTMLElement|null} - найденный элемент или null
|
||
*
|
||
* @example
|
||
* const row = closest(button, '.chat-row');
|
||
*/
|
||
export function closest(element, selector) {
|
||
if (!element) return null;
|
||
return element.closest(selector);
|
||
}
|
||
|
||
/**
|
||
* Безопасно получает элемент по ID
|
||
*
|
||
* @param {string} id - ID элемента
|
||
* @returns {HTMLElement|null} - элемент или null
|
||
*
|
||
* @example
|
||
* const el = getById('myElement');
|
||
*/
|
||
export function getById(id) {
|
||
return document.getElementById(id);
|
||
}
|
||
|
||
/**
|
||
* Безопасно получает первый элемент по селектору
|
||
*
|
||
* @param {string} selector - CSS селектор
|
||
* @param {HTMLElement|Document} [context=document] - контекст поиска
|
||
* @returns {HTMLElement|null} - элемент или null
|
||
*
|
||
* @example
|
||
* const el = querySelector('.my-class');
|
||
* const child = querySelector('.child', parentElement);
|
||
*/
|
||
export function querySelector(selector, context = document) {
|
||
if (!context) return null;
|
||
return context.querySelector(selector);
|
||
}
|
||
|
||
/**
|
||
* Безопасно получает все элементы по селектору
|
||
*
|
||
* @param {string} selector - CSS селектор
|
||
* @param {HTMLElement|Document} [context=document] - контекст поиска
|
||
* @returns {HTMLElement[]} - массив элементов
|
||
*
|
||
* @example
|
||
* const items = querySelectorAll('.item');
|
||
* items.forEach(item => console.log(item));
|
||
*/
|
||
export function querySelectorAll(selector, context = document) {
|
||
if (!context) return [];
|
||
return Array.from(context.querySelectorAll(selector));
|
||
}
|