Мне нужно сделать полоску, которая передвигается в зависимости от активного элемента навигации в шапке. Как это сделать?

Всем привет! мне нужно сделать такую плашку как на скриншоте, она должна ездить к активным пунктам меню, у меня уже реализован функционал нахождения активного элемента при скролле страницы через IntersectionObserver.

JS

const activeElementLine = document.querySelector('.body-header__active-el-line');

const observer = new IntersectionObserver(
    (entries) => {
        entries.forEach((entry) => {
            if (entry.isIntersecting) {
                document.querySelectorAll('.body-header__item').forEach((link) => {
                    let id = link.dataset.goto.replace('#', '');
                    if (id === entry.target.id) {
                        link.classList.add('body-header__item--active');
                        const activeLink = document.querySelector('.body-header__item--active');
                    } else {
                        link.classList.remove('body-header__item--active');
                    }
                });
            }
        });
    },
    {
        threshold: 0.8,
    }
);

document.querySelectorAll('.section').forEach((section) => {
    observer.observe(section);
});

HTML

<section class="header__body body-header">
        <nav class="body-header__nav">
            <ul class="body-header__list">
                <li data-goto="#intro" class="body-header__item">Главная</li>
                <li data-goto="#about" class="body-header__item">Обо мне</li>
                <div class="body-header__active-el-line"></div>

            </ul>
        </nav>
    </section>

Скриншот того, как надо сделать


Ответы (1 шт):

Автор решения: Meth0d

Например, так. Здесь на примере кнопок. С обсервером вы просто передаете в этот коллбэк data-tab элемента, который пересекаем.

const items = document.querySelectorAll('.item')
const glider = document.querySelector('.glider')
const width = 120
const gap = 24

items.forEach(item => item.addEventListener('click', _ => {
    const tab = item.dataset.tab

    glider.style.transform = `translateX(${width * tab + (tab > 0 ? gap : 0)}px)`
}))
.row {
    position: relative;
    display: flex;
    gap: 24px;
    padding: 20px;
}
.item {
    width: 120px;
    background: none;
    border: none;
    cursor: pointer;
}
.glider {
    position: absolute;
    width: 120px;
    height: 2px;
    bottom: 10px;
    background-color: teal;
    transition: all .2s;
}
<div class="row">
    <button class="item" data-tab="0">Main</button>
    <button class="item" data-tab="1">About</button>
    <div class="glider"></div>
</div>

→ Ссылка