This question already has answers here:
Animate counter when in viewport
                                
                                    (3个答案)
                                
                        
                                3年前关闭。
            
                    
我正在尝试将数字放在视口中时进行计数,但是目前,我正在使用的脚本会中断滚动计数。

我将如何制作它以使其忽略滚动并仅在视口内向上计数?这需要在移动设备上工作,因此即使用户在触摸时滚动。它不能中断计数。

请在这里查看:
http://jsfiddle.net/Q37Q6/27/

(function ($) {

$.fn.visible = function (partial, hidden) {

    var $t = $(this).eq(0),
        t = $t.get(0),
        $w = $(window),
        viewTop = $w.scrollTop(),
        viewBottom = viewTop + $w.height(),
        _top = $t.offset().top,
        _bottom = _top + $t.height(),
        compareTop = partial === true ? _bottom : _top,
        compareBottom = partial === true ? _top : _bottom,
        clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;

    return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
};

})(jQuery);


// Scrolling Functions
$(window).scroll(function (event) {
function padNum(num) {
    if (num < 10) {
        return "" + num;
    }
    return num;
}

var first = 25; // Count up to 25x for first
var second = 4; // Count up to 4x for second
function countStuffUp(points, selector, duration) { //Animate count
    $({
        countNumber: $(selector).text()
    }).animate({
        countNumber: points
    }, {
        duration: duration,
        easing: 'linear',
        step: function () {
            $(selector).text(padNum(parseInt(this.countNumber)));
        },
        complete: function () {
            $(selector).text(points);
        }
    });
}

// Output to div
$(".first-count").each(function (i, el) {
    var el = $(el);
    if (el.visible(true)) {
        countStuffUp(first, '.first-count', 1600);
    }
});

// Output to div
$(".second-count").each(function (i, el) {
    var el = $(el);
    if (el.visible(true)) {
        countStuffUp(second, '.second-count', 1000);
    }
});

});

最佳答案

我认为,您的示例比您所知道的要复杂。您正在以一种非常不寻常的方式来做事,这里,在自定义属性上使用jQuery animate方法作为计数器。这很酷,但也使事情变得更加复杂。我不得不添加一些东西来理顺这种情况。


我继续重写了可见的插件,主要是因为我不知道您的插件在做什么。这很简单!
当您的计数器变为可见状态时,它们将获得“计数”类,这样在已经计数时不会在其上重新触发计数器。
我将对您具有自定义计数器动画的对象的引用保存到计数器的data属性上。这至关重要:没有该参考,动画在屏幕外播放时就无法停止。
我在步进功能中做了一些幻想,以跟踪还剩多少时间,以便即使计数器停止运行也可以使计数器以相同的速度运行。如果您的计数器运行半秒,并且整个动画设置为使用一秒钟,则如果动画被中断并重新启动,则只需要在重新启动计数器时将其设置为半秒即可。


http://jsfiddle.net/nate/p9wgx/1/

(function ($) {

    $.fn.visible = function () {

        var $element = $(this).eq(0),
            $win = $(window),

            elemTop = $element.position().top,
            elemBottom = elemTop + $element.height(),

            winTop = $win.scrollTop(),
            winBottom = winTop + $win.height();

        if (elemBottom < winTop) {
            return false;
        } else if (elemTop > winBottom) {
            return false;
        } else {
            return true;
        }
    };

})(jQuery);

function padNum(num) {
    if (num < 10) {
        return " " + num;
    }
    return num;
}


var $count1 = $('.first-count');
var $count2 = $('.second-count');

// Scrolling Functions
$(window).scroll(function (event) {
    var first = 25; // Count up to 25x for first
    var second = 4; // Count up to 4x for second

    function countStuffUp(points, selector, duration) {
        //Animate count
        var $selector = $(selector);
        $selector.addClass('counting');

        var $counter = $({
            countNumber: $selector.text()
        }).animate({
            countNumber: points
        }, {
            duration: duration,
            easing: 'linear',
            step: function (now) {
                $selector.data('remaining', (points - now) * (duration / points));
                $selector.text(padNum(parseInt(this.countNumber)));
            },
            complete: function () {
                $selector.removeClass('counting');
                $selector.text(points);

            }
        });

        $selector.data('counter', $counter);
    }

    // Output to div
    $(".first-count").each(function (i, el) {
        var el = $(el);
        if (el.visible() && !el.hasClass('counting')) {
            var duration = el.data('remaining') || 1600;
            countStuffUp(first, '.first-count', duration);
        } else if (!el.visible() && el.hasClass('counting')) {
            el.data('counter').stop();
            el.removeClass('counting');
        }
    });

    // Output to div
    $(".second-count").each(function (i, el) {
        var el = $(el);
        if (el.visible() && !el.hasClass('counting')) {
            var duration = el.data('remaining') || 1000;
            countStuffUp(second, '.second-count', duration);
        } else if (!el.visible() && el.hasClass('counting')) {
            el.data('counter').stop();
            el.removeClass('counting');
        }
    });
});


这里有很多东西。如有疑问,请随时问我。

09-27 04:53