@scaardss

Как добавить класс когда элемент появляется в область видимости?

Здравствуйте, подскажите как добавить класс к элементу, только когда тот попадает в зону видимости?
Сам пока только до такого дошел:
<div class="wrapper">
        <div class="item go animated"></div>
        <div class="box"></div>
        <div class="item1 go"></div>
    </div>

.wrapper{
    width: 175px;
    margin: 0 auto;
}
.item{
    width: 175px;
    height: 175px;
    background-color: mediumvioletred;
    top: 130%;
    position: absolute;
}
.item1{
    width: 175px;
    height: 175px;
    background-color: mediumvioletred;    
}
.box{
    height: 200vh;
}
.go{
    opacity: 0;    
}
.go.active{
    opacity: 1;
}

$(document).ready(function(){
    var window_h = $(window).height();
    var m_top = $('.go').offset().top;
        $(window).scroll(function(){
            var scrollTop = $(window).scrollTop() - 200;
            var raznost = m_top - window_h;
            if (scrollTop > m_top - window_h) {
                $('.go').addClass('active bounceInLeft');    
            }
        });
});

Но в таком варианте класс добавляется сразу ко всем элементам с классом "go", => анимация видна только у первого блока.
Подскажите, как сделать, чтобы при расчетах высота от блока до верха страницы (offset().top) бралась для каждого блока своя?
  • Вопрос задан
  • 908 просмотров
Пригласить эксперта
Ответы на вопрос 3
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Вот этоvar m_top = $('.go').offset().top;запомнит оффсет только для самого первого элемента найденного по селектору, поэтому и обрабатывается только он.
Использовать событие scroll для отслеживания вьюпорта - это наплевательское отношение к ресурсам пользователя, ведь есть более эффективное апи для этого - IntersectionObserver
Пример:
$(document).ready(function(){
  var observer = new IntersectionObserver(function(entries){
    entries.forEach(function(entry){
      if(entry.isIntersecting) {
        $(entry.target).addClass('active bounceInLeft');
      } else {
        $(entry.target).removeClass('active bounceInLeft');
      }
    });
  }, {threshold: 0.1});
  $('.go').each(function(){
    observer.observe(this);
  });
});

Если нужен IE или Safari старее 12, то вот полифил: https://www.npmjs.com/package/intersection-observer
Ответ написан
Комментировать
ArsenyMatytsyn
@ArsenyMatytsyn Куратор тега JavaScript
Руководитель frontend направления, предприниматель
Тебе нужно в цикле перебирать элементы и каждому вешать слушатель. А ты вешаешь класс ко всем сразу.
Ответ написан
ThunderCat
@ThunderCat Куратор тега JavaScript
{PHP, MySql, HTML, JS, CSS} developer
у вас как-то логика в коде отсутствует, вы СНАЧАЛА вычисляете оффсет набора элементов $('.go').offset().top;, и с ним сравниваете текущую позицию.
Как вариант - по скроллу выбирать элементы с классом го, перебирать их, и если они в нужной позиции - убирать класс го и добавлять ваш актив. тогда при следующем скролл евенте в выборку уже не попадут те которые с актив но без го.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы