Я сделал анимацию обратного отсчета с помощью 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>
Как я могу это решить?
Используйте $(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>