Активировать анимацию после прокрутки за пределы определенной точки в документе

Я сделал анимацию обратного отсчета с помощью js, но счетчик запускает анимацию обратного отсчета, когда я обновляю страницу (не имеет значения, где я нахожусь, вижу я это или нет).

Я хочу, чтобы счетчик начал работать только тогда, когда счетчик div находится в точке обзора (когда я прокручиваю вниз и вижу его).

HTML

<div class = "content bg-warning">
    <div class = "row m-0 py-5 d-flex justify-content-center">
        <div class = "counter" data-count = "2200" style = "color: white; font-size: 32px; font-weight: bold;">0</div>
    </div>
</div>

js

<script type = "text/javascript">
    $('.counter').each(function() {
      var $this = $(this),
          countTo = $this.attr('data-count');
      
      $({ countNum: $this.text()}).animate({
        countNum: countTo
      },

      {
        duration: 8000,
        easing:'linear',
        step: function() {
          $this.text(Math.floor(this.countNum));
        },
        complete: function() {
          $this.text(this.countNum);
          //alert('finished');
        }

      });  

    });
</script>

Как я могу это решить?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
352
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте $(window).scroll() для отслеживания текущей позиции прокрутки (срабатывает один раз для каждого прокручиваемого пикселя)
Используйте $(window).scrollTop(), чтобы получить текущую позицию прокрутки*
Используйте $(element).offset(), чтобы получить координаты .top и .left элемента*
Используйте $(window).height(), чтобы получить высоту окна просмотра

* calculated from top of document

Вы хотите рассчитать, насколько ниже нижней части области просмотра находится элемент, к которому вы прокручиваете. Этот расчет (упрощенный):

element_position - viewport_height = расстояние ниже сгиба

Важно: обратите внимание, что window.scroll() срабатывает один раз для каждого прокручиваемого пикселя. Это здорово, но это может затормозить ваше приложение. Обычным решением является реализация дебаунсера. Видеть:

https://davidwalsh.name/javascript-debounce-function

Вот пример:

var st = $(window).scrollTop();
var fin = calcWhenDivInWindow();
var off = 20; //How far counter div must be above bottom of screen before count begins

$(window).scroll(function(){
    st = $(this).scrollTop();
    if (st > fin+off) doCount();
});

function doCount(){
    $('.counter').each(function() {
      var $this = $(this),
          countTo = $this.attr('data-count');

      $({ countNum: $this.text()}).animate({
        countNum: countTo
      },
      {
        duration: 8000,
        easing:'linear',
        step: function() {
          $this.text(Math.floor(this.countNum));
        },
        complete: function() {
          $this.text(this.countNum);
        }
      });  
    });
}
function calcWhenDivInWindow(){
    var tt = $('.content').offset().top;
    var th = $('.content').outerHeight();
    var ww = $(window).height();
    return tt+th-ww;
}
*{font-family:Arial;font-size:1.2rem;}

.stuff1{height:80vh;width:98vw;background:pink;}
.stuff2{height:50vh;width:98vw;background:lightblue;}
.stuff3{height:50vh;width:98vw;background:palegreen;}
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.min.css"/>
<link rel = "stylesheet" href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/countUp.min.js">
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

<div class = "stuff1">Stuff n Nonsense (scroll slowly...)</div>
<div class = "stuff2">More Stuff n Nonsense</div>

<div class = "content bg-warning">
    <div class = "row m-0 py-5 d-flex justify-content-center">
        <div class = "counter" data-count = "2200" style = "color: white; font-size: 32px; font-weight: bold;">0</div>
    </div>
</div>

<div class = "stuff3"></div>

Другие вопросы по теме