добавление класса в элемент в окне просмотра

#javascript #html #jquery #css #web

Вопрос:

У меня на странице пять разделов, и я пытаюсь добавить класс «активный» в раздел в окне просмотра. Я попробовал этот код, но он работает неправильно. код сохраняет все элементы с именем тега «раздел» в списке узлов, затем создает массив из этого списка, я зациклился на массиве и добавил прослушиватель событий для каждого элемента, затем я проверил, находится ли элемент в окне просмотра, поэтому я добавляю класс, иначе я удаляю класс. проблема в том, что после прокрутки страницы все пять разделов будут иметь класс «активный», что означает, что несколько элементов имеют класс «активный» одновременно, даже если в порту просматривается только один раздел, и когда я продолжаю прокручивать вниз, разделы, которые перемещаются вверх из окна просмотра, удаляют их класс «активный». как я могу одновременно иметь один элемент с изображением кода класса «активный»?

 //values of viewport
const viewWidth = document.documentElement.clientWidth;
const viewHeight = document.documentElement.clientHeight;

//set class active to section in viewport
function sectionInView(x) {
    for (let i = 0; i in x; i  ) {
        document.addEventListener("scroll", function () {
            let el = x[i].getBoundingClientRect();
            if (el.top >= 0 amp;amp; el.left >= 0 amp;amp; el.bottom <= viewHeight amp;amp; el.right <= viewWidth) {
                x[i].setAttribute("class", "active your-active-class");

            }
            else {

                x[i].removeAttribute("class", "active your-active-class");
            }
        });
    }
}
sectionInView(sectionListArray);
 

Комментарии:

1. Это очень странное поведение. Почему бы вам не подождать, пока пользователь откроет интересующий его раздел, вместо того, чтобы открывать/закрывать разделы в зависимости от окна просмотра?

2. почему бы не использовать classList.add() и classList.remove() вместо setAttribute этого ?

3. @Azu это требование в проекте, над которым я работаю

4. @tacoshy изменило бы это поведение кода?

5. Вы исследовали IntersectionObserver?

Ответ №1:

 let sectionListArray = document.querySelectorAll('section')
const viewHeight = document.documentElement.clientHeight
         window.onscroll = (() => {
            sectionListArray.forEach(function(v) {
                let rect = v.getBoundingClientRect();
                let y = rect.y;
                let bottom = rect.bottom;
                let height = rect.height;
                if (y > viewHeight|| bottom height < viewHeight ) {
                    v.classList.add('active')
                } else {
                    v.classList.remove('active')
                }
            })
        })
         
 section {
            height: 300px;
            background: red;
            margin-bottom: 10px;
            transition: 1s;
            opacity:1
        }
.active{
opacity:0
} 
 <section></section>
<section></section>
<section></section>
<section></section>
<section></section>
<section></section>
<section></section>
<section></section>
<section></section>