我正在尝试在滚动的同一页上设置两组数字的动画。以下代码有效,但我注意到启动速度较慢,并且完成动画所需的时间更长。我还认为代码可以优化和改进。
JS
// Animated numbers when scrolled to
var a = 0;
$(window).scroll(function() {
var oTop1 = $('.counter-1').offset().top - window.innerHeight;
var oTop2 = $('.counter-2').offset().top - window.innerHeight;
if (a == 0 && $(window).scrollTop() > oTop1) {
$('.animate-numbers-1').each(function() {
var $this = $(this),
countTo = $this.attr('data-target');
$({
countNum: $this.text()
}).animate({
countNum: countTo
},
{
duration: 1000,
easing: 'swing',
step: function() {
$this.text(Math.floor(this.countNum));
},
complete: function() {
$this.text(this.countNum);
//alert('finished');
}
});
});
}
if (a == 0 && $(window).scrollTop() > oTop2) {
$('.animate-numbers-2').each(function() {
var $this = $(this),
countTo = $this.attr('data-target');
$({
countNum: $this.text()
}).animate({
countNum: countTo
},
{
duration: 2500,
easing: 'swing',
step: function() {
$this.text(Math.floor(this.countNum));
},
complete: function() {
$this.text(this.countNum);
//alert('finished');
}
});
});
}
});
我们将不胜感激。
答案 0 :(得分:1)
$(window).scroll()
在很短的时间内就会产生数百个事件。
在您的代码中,每个动画事件(几秒钟内发生数百次)都指定持续时间为一秒。因此:数百个事件(每个事件需要一秒钟)都需要在几秒钟内发生。经济增长放缓并不令人惊讶。
如果有一种方法可以限制事件,以便每隔几毫秒就触发一个事件,那不是很好吗?还是这样,只有一个事件会触发,直到间隔了几毫秒?
去抖动器 可确保对于可能发生很多次的事件仅发送一个信号。 限制 限制了函数在固定时间间隔内收到的调用次数-例如,每500ms仅发生一个事件。)或者,如Chris Coyer explains the two:< / p>
限制功能可随时间推移强制调用函数的最大次数。就像“每100毫秒最多执行一次此功能”。
和
去抖强制执行一个函数,直到经过一定时间后才再次调用该函数。就像“只有在没有调用它的情况下经过100毫秒时才执行此函数。”
In this article,大卫·沃尔什(David Walsh)解释了此非常流行的去抖动功能,该功能来自underscore.js:
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Walsh用来演示如何使用上述功能的示例是:
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
window.addEventListener('resize', myEfficientFn);
参考文献:
https://davidwalsh.name/javascript-debounce-function
https://css-tricks.com/the-difference-between-throttling-and-debouncing/
答案 1 :(得分:1)
在我的第一个答案中,我可能误解了您代码的性质。当window.scroll到达适当元素的顶部时,可能只需要动画运行一次。如果是这样,那么您所需要的只是一个指示符,以跟踪动画的状态:在动画执行之前为false,之后为true。 仅当指示器为假时才运行动画。
您可以为此使用全局变量-或仅将类添加到触发元素。缺少类(false)表示该动画尚未运行,具有类的表示该动画已经运行。
// Animated numbers when scrolled to
var a = 0;
$(window).scroll(function() {
var oTop1 = $('.counter-1').offset().top - window.innerHeight;
var oTop2 = $('.counter-2').offset().top - window.innerHeight;
var done1 = $('.counter-1').hasClass('ani-done');
var done2 = $('.counter-2').hasClass('ani-done');
if (!done1 && a == 0 && $(window).scrollTop() > oTop1) {
$('.animate-numbers-1').each(function() {
//animation goes here
});
$('.counter-1').addClass('ani-done');
}
if (!done2 && a == 0 && $(window).scrollTop() > oTop2) {
$('.animate-numbers-2').each(function() {
//animation goes here
});
$('.counter-2').addClass('ani-done');
}
});