Анимировать счетчик при прокрутке мимо части Div?

#javascript #html #css

#javascript #HTML #css

Вопрос:

Я создал раздел счетчика на своем сайте, который анимируется при загрузке страницы, однако я пытаюсь запустить анимацию, когда пользователь попадает в этот раздел.

В настоящее время у меня есть это, однако анимация запускается только тогда, когда div находится за пределами навигации, т. е. в верхней части экрана, включая навигацию. Как бы мне изменить это, чтобы анимация запускалась, когда div становится видимым?

У меня также возникла проблема с тем, что он показывает, чтобы начинаться с полного числа без запятых, а затем переходит к 0 и анимируется, как я могу заставить его показывать 0 для начала?

Я довольно новичок в JS, поэтому был бы признателен за любое объяснение этого.

Вот что у меня есть:

 const convert = str => {
  // Find the number
  let regx = /(d{1,3})(d{3}(?:,|$))/;
  // Set a variable
  let currStr;
  // Start loop
  do {
    // Replace current string, split it
    currStr = (currStr || str.split(`.`)[0])
      .replace(regx, `$1,$2`)
  } while (currStr.match(regx)); // Loop

  // Return our result from function
  return (str.split(`.`)[1]) ?
    currStr.concat(`.`, str.split(`.`)[1]) :
    currStr;
};

$(window).scroll(startCounter);

function startCounter() {
  if ($(window).scrollTop() > $('#counter').offset().top) {
    $(window).off("scroll", startCounter);
    $('.count').each(function() {
      $(this).prop('Counter', 0).animate({
        Counter: $(this).text()
      }, {
        duration: 2000,
        easing: 'swing',
        step: function(now) {
          $(this).text(Math.ceil(now));
          $(this).text(convert($(this).text()))
        }
      });
    });
  }
}  
 .section-counter {
  margin-top: 150vh;
  margin-bottom: 150vh;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="section-counter" id="counter">

  <div class="row">
    <h2>Headline Data Figures</h2>
  </div>

  <div class="row">
    <div class="col span-1-of-2">
      <div class="row">
        <div id="shiva"><span class="count">1688019</span>
          <h3>Contributions</h3>
        </div>
      </div>

      <div id="shiva"><span class="count">82150</span>
        <h3>Items of Business</h3>
      </div>

    </div>

    <div class="col span-1-of-2">
      <div class="row">
        <div id="shiva"><span class="count">10505</span>
          <h3>Meetings</h3>
        </div>
      </div>

      <div id="shiva"><span class="count">168260</span>
        <h3>Writtenamp;#47;Oral Questions</h3>
      </div>
    </div>
  </div>

  <div class="row arrow-dark arrow__7 animated pulse infinite">
    <i class="ion-md-arrow-dropdown"></i>
  </div>

</section>  

Ответ №1:

Если я правильно понимаю, проблема в том, что вы сравниваете смещение div к верхней части экрана, когда на самом деле вы хотели бы выяснить, где находится нижняя часть экрана, и сравнить это с положением div.

Что касается начала с 0 , вы можете заставить элементы использовать атрибут data для определения максимального значения вместо текста, таким образом, вы можете читать элементы 0 до тех пор, пока они не начнут подсчет:

 const convert = str => {
  // Find the number
  let regx = /(d{1,3})(d{3}(?:,|$))/;
  // Set a variable
  let currStr;
  // Start loop
  do {
    // Replace current string, split it
    currStr = (currStr || str.split(`.`)[0])
      .replace(regx, `$1,$2`)
  } while (currStr.match(regx)); // Loop

  // Return our result from function
  return (str.split(`.`)[1]) ?
    currStr.concat(`.`, str.split(`.`)[1]) :
    currStr;
};

$(window).scroll(startCounter);

function startCounter() {
  var bottomOfScreen = $(window).scrollTop()   $(window).innerHeight();
  if (bottomOfScreen > $('#counter').offset().top) {
    $(window).off("scroll", startCounter);
    $('.count').each(function() {
      $(this).prop('Counter', 0).animate({
        Counter: $(this).attr('data-max')
      }, {
        duration: 2000,
        easing: 'swing',
        step: function(now) {
          $(this).text(Math.ceil(now));
          $(this).text(convert($(this).text()))
        }
      });
    });
  }
}  
 .section-counter {
  margin-top: 150vh;
  margin-bottom: 150vh;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="section-counter" id="counter">

  <div class="row">
    <h2>Headline Data Figures</h2>
  </div>

  <div class="row">
    <div class="col span-1-of-2">
      <div class="row">
        <div id="shiva"><span class="count" data-max="1688019">0</span>
          <h3>Contributions</h3>
        </div>
      </div>

      <div id="shiva"><span class="count" data-max="812150">0</span>
        <h3>Items of Business</h3>
      </div>

    </div>

    <div class="col span-1-of-2">
      <div class="row">
        <div id="shiva"><span class="count" data-max="10505">0</span>
          <h3>Meetings</h3>
        </div>
      </div>

      <div id="shiva"><span class="count" data-max="168260">0</span>
        <h3>Writtenamp;#47;Oral Questions</h3>
      </div>
    </div>
  </div>

  <div class="row arrow-dark arrow__7 animated pulse infinite">
    <i class="ion-md-arrow-dropdown"></i>
  </div>

</section>  

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

1. Это отлично работает, однако начинается слишком рано, не могли бы вы немного подсказать мне, что для этого нужно изменить?

2. На самом деле, все в порядке, я разобрался с этой частью, спасибо!

Ответ №2:

Я дам вам логику для запуска анимации, как только пользователь доберется до элемента.

Соответствующим триггером события является ONMOUSEOVER, поэтому для его включения…

  <div id="abc" onmouseover="AnimateIt();"></div>
  

Излишне упоминать, что для начала в стиле нашего элемента анимация должна быть ПРИОСТАНОВЛЕНА, вот так…

   animation-play-state:paused;
  

Итак, логика JavaScript для анимации…

  function AnimateIt(){ abc.style.animationPlayState='running'; }
  

Вот и все.

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

1. Спасибо, однако я не ищу триггер наведения курсора мыши. У меня уже работает scrollTop, но я хочу запустить его до того, как он попадет в верхнюю часть экрана. Что-то вроде этого: jsfiddle.net/Yy6r6/422

2. Вы сказали «Я пытаюсь запустить анимацию, когда пользователь попадает в этот раздел», и это ИМЕННО то, что я вам дал.

3. Я добавил top — $ (‘nav’).height() и это, казалось, дало больше того, к чему я стремлюсь. Однако счетчик все еще не начинается с 0.

4. Извините, я не использую сторонние $… Я использую только правильный javascript. Спасибо и удачи.

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