Можно через IntersectionObserver, например :)
if ('IntersectionObserver' in window &&
'IntersectionObserverEntry' in window &&
'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
if (!('isIntersecting' in IntersectionObserverEntry.prototype)) {
Object.defineProperty(window.IntersectionObserverEntry.prototype, 'isIntersecting', {
get: function() { return this.intersectionRatio > 0; }
});
}
var oObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
// делаем анимацию (добавляем css-класс в котором настроены анимации)
entry.target.classList.add('animate');
}
});
});
// вешаем observer на массив элементов
arrayElements.forEach(function(elem) {
oObserver.observe(elem);
});
}