【问题标题】:Multiple viewport checks per page每页多个视口检查
【发布时间】:2019-02-22 15:17:19
【问题描述】:

我正在使用脚本来计算从 0 到实际值的数字。 要启动计数器,我希望元素位于视口的可见区域中。

我找到了一个检查元素是否在可见区域中的解决方案。 但如果我在页面的不同区域使用多个数字元素,这将不起作用。它计算具有相同类的每个元素 (.counter)。

如果我两次使用不同名称的计数器脚本,第二个版本不起作用,第一个版本在滚动时不起作用。仅当我在页面加载的可见区域中有计数器时。

这是我的计数器代码:

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

    $({ countNum: $this.text()}).animate({
        countNum: countTo
    },

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

    });

});

这是我尝试过的解决方案(每页工作一次):https://stackoverflow.com/a/488073/1788961

在这里你可以找到一个完整的代码:https://codepen.io/cray_code/pen/QYXVWL

这是检查我是否滚动到元素的代码(请参阅上面的链接答案):

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}


function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

【问题讨论】:

    标签: javascript jquery counter viewport


    【解决方案1】:

    您检查 isElementInView 一次,而不是单独检查每个元素。当然它会启动所有计数器。

    var isElementInView = Utils.isElementInView($('.counter'), false);
    if (isElementInView) {
                $('.counter').each(function() {
    

    将它移动到您的 .each 函数中,它将分别适用于每个计数器。

    $('.counter').each(function() {
                    var $this = $(this),
                    countTo = $this.attr('data-count');
                    var isElementInView = Utils.isElementInView($this, false);
                    if (isElementInView) {
                    // do animation
    

    如果您希望在滚动时发生这种情况,则需要在每次滚动时执行代码的页面中添加一个 EventListener:https://developer.mozilla.org/en-US/docs/Web/Events/scroll

    function checkForVisible(){
        $('.counter').each(function() {
                    var $this = $(this),
                    countTo = $this.attr('data-count');
                    var isElementInView = Utils.isElementInView($this, false);
                    if (isElementInView) {
                    // etc code
    }
    
    var ticking = false;
    window.addEventListener('scroll', function(e) {
      if (!ticking) {
        window.requestAnimationFrame(function() {
          checkForVisible();
          ticking = false;
        });
        ticking = true;
      }
    });
    

    【讨论】:

    • 好的,谢谢。现在它可以工作,但前提是计数器位于页面加载时的可见区域。当我滚动到计数器时,它保持在 0
    • 您的评论描述了您的要求的第一行(在问题中)-您需要检查 window/div 滚动事件(对其进行去抖动并检查是否已经启动)-而不仅仅是在启动时进行一次
    • @Cray 因为它只在页面加载时执行一次。我通过引用滚动事件侦听器编辑了答案。
    • 我以为我正在使用类似的东西。在上面的问题中查看我的编辑。如果只有一个计数器,则此方法有效。
    • 你的工具只是检查元素在执行时是否在视图中。它不会永久检查它。我将在答案中添加事件侦听器代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多