Привет всем! У меня возник вопрос по разработке компонента для выделения текста, где при наведении курсора на выделенный текст или связанный комментарий оба элемента должны выделяться. Сейчас я использую обработчики onMouseEnter и onMouseLeave для добавления класса ‘.hover’, но мне кажется, что можно реализовать это проще. Может быть, существует что-то вроде атрибута ‘for’ у label, который связывает элементы? Буду рад услышать ваши предложения по реализации этого функционала на чистом JavaScript без фреймворков.
function highlightSegment(text) {
const element = document.createElement('span');
element.className = 'highlighted';
element.textContent = text;
return element;
}
function generateComment(text) {
const element = document.createElement('div');
element.className = 'commentBox';
element.textContent = text;
return element;
}
// Здесь нужно реализовать механизм связывания между выделенным текстом и комментарием
Заранее спасибо за помощь!
Можно использовать делегирование событий и data-атрибуты для связывания элементов. Добавь одинаковый data-id к выделенному тексту и комментарию. Затем навесь обработчик mouseenter/mouseleave на общий контейнер:
container.addEventListener(‘mouseenter’, (e) => {
if (e.target.matches(‘.highlighted, .commentBox’)) {
const id = e.target.dataset.id;
document.querySelectorAll([data-id=\"${id}\"]
).forEach(el => el.classList.add(‘hover’));
}
}, true);
Так избежишь дублирования обработчиков и свяжешь элементы без лишнего кода.
Можно попробовать использовать MutationObserver для отслеживания изменений в DOM. Создаем observer, который следит за добавлением выделенного текста и комментариев. Когда элементы появляются, связываем их через уникальный id. Потом навешиваем один обработчик на родителя:
document.body.addEventListener(‘mouseover’, (e) => {
let target = e.target.closest(‘.highlighted, .commentBox’);
if (target) {
let linked = document.querySelector([data-link=\"${target.dataset.link}\"]
);
target.classList.add(‘hover’);
linked?.classList.add(‘hover’);
}
});