在视口

时间:2016-04-06 15:22:16

标签: jquery html counter viewport

我有一个计数器,它动画到HTML中定义的最终数字。但是我希望这个动画一旦出现在视口中就会发​​生。

我有fiddle here,显示滚动似乎如何影响计数器编号。

$(document).ready(function() {
      $(function($, win) {
        $.fn.inViewport = function(cb) {
          return this.each(function(i, el) {
            function visPx() {
              var H = $(this).height(),
                r = el.getBoundingClientRect(),
                t = r.top,
                b = r.bottom;
              return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
            }
            visPx();
            $(win).on("resize scroll", visPx);
          });
        };
      }(jQuery, window));

      $(".fig-number").inViewport(function(px) {
        $(this).each(function() {
          $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
          }, {
            duration: 1000,

            step: function(now) {
              $(this).text(Math.ceil(now));
            }
          });
        });
      });
    });

我尝试了很多东西,但我似乎无法实现我所追求的目标。

$(document).ready(function() {
  $(function($, win) {
    $.fn.inViewport = function(cb) {
      return this.each(function(i, el) {
        function visPx() {
          var H = $(this).height(),
            r = el.getBoundingClientRect(),
            t = r.top,
            b = r.bottom;
          return cb.call(el, Math.max(0, t > 0 ? H - t : (b < H ? b : H)));
        }
        visPx();
        $(win).on("resize scroll", visPx);
      });
    };
  }(jQuery, window));

  $(".fig-number").inViewport(function(px) {
    $(this).each(function() {
      $(this).prop('Counter', 0).animate({
        Counter: $(this).text()
      }, {
        duration: 1000,

        step: function(now) {
          $(this).text(Math.ceil(now));
        }
      });
    });
  });
});
html,
body {
  height: 100%;
}
#upper-push {
  height: 100%;
  width: 100%;
  display: block;
  background: red;
  color: white;
}
<div id="upper-push">
  Scroll down
</div>
<div id="numbers">
  <span class="fig-number">25</span>
  <span class="fig-number">78</span>
</div>

3 个答案:

答案 0 :(得分:12)

.inViewport() plugin会在每个滚动事件上触发回调。
这是设计的。 (有助于在代码中保留插件的来源!;))

"plugin page"上,您可以看到如何使用它:

$("selector").inViewport(function(px) {
  console.log( px ); // `px` represents the amount of visible height
  if(px){
    // do this if element enters the viewport // px > 0
  }else{
    // do that if element exits  the viewport // px = 0
  }
}); // Here you can chain other jQuery methods to your selector 

这意味着:

  1. 您必须聆听 px参数大于0 (元素在视口中)
  2. 要防止链接其他动画创建累积,您应该使用标记变量
  3. (不需要回调中的$(this).each()。插件已经在一组元素上运行。)
  4. <强> Edited jsFiddle demo

    jQuery(function($) { // DOM ready and $ in scope
    
      $(".fig-number").inViewport(function(px) {
        // if px>0 (entered V.port) and
        // if prop initNumAnim flag is not yet set = Animate numbers
        if(px>0 && !this.initNumAnim) { 
          this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
          // <<< DO SOME COOL STUFF HERE! 
        }
      });
    
    });
    

    摘录示例:

    // inViewport jQuery plugin
    // https://stackoverflow.com/a/26831113/383904
    $(function($, win) {
      $.fn.inViewport = function(cb) {
        return this.each(function(i,el){
          function visPx(){
            var H = $(this).height(),
                r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
            return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));  
          } visPx();
          $(win).on("resize scroll", visPx);
        });
      };
    }(jQuery, window));
    
    
    jQuery(function($) { // DOM ready and $ in scope
    
      $(".fig-number").inViewport(function(px) { // Make use of the `px` argument!!!
        // if element entered V.port ( px>0 ) and
        // if prop initNumAnim flag is not yet set
        //  = Animate numbers
        if(px>0 && !this.initNumAnim) { 
          this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
          $(this).prop('Counter',0).animate({
            Counter: $(this).text()
          }, {
            duration: 1000,
            step: function (now) {
              $(this).text(Math.ceil(now));
            }
          });         
        }
      });
    
    });
    html,
    body {
      height:100%;
    }
    
    #upper-push {
      height:100%;
      width:100%;
      display:block;
      background:red;
      color:white;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="upper-push">
      Scroll down
    </div>
    <div id="numbers">
      <span class="fig-number">25</span>
      <span class="fig-number">78</span>
    </div>

答案 1 :(得分:7)

如果您不介意更改代码,则可以解决此问题。  jsfiddle

    var $findme = $('#numbers');
var exec = false;
function Scrolled() {
  $findme.each(function() {
    var $section = $(this),
      findmeOffset = $section.offset(),
      findmeTop = findmeOffset.top,
      findmeBottom = $section.height() + findmeTop,
      scrollTop = $(document).scrollTop(),
      visibleBottom = window.innerHeight,
      prevVisible = $section.prop('_visible');

    if ((findmeTop > scrollTop + visibleBottom) ||
      findmeBottom < scrollTop) {
      visible = false;
    } else visible = true;

    if (!prevVisible && visible) {
    	if(!exec){
              $('.fig-number').each(function() {
          $(this).prop('Counter', 0).animate({
            Counter: $(this).text()
          }, {
            duration: 1000,

            step: function(now) {
              $(this).text(Math.ceil(now));
              exec = true;
            }
          });
        });
      }
    }
    $section.prop('_visible', visible);
  });

}

function Setup() {
  var $top = $('#top'),
    $bottom = $('#bottom');

  $top.height(500);
  $bottom.height(500);

  $(window).scroll(function() {
    Scrolled();
  });
}
$(document).ready(function() {
  Setup();
});
html,
body {
  height: 100%;
}

#upper-push {
  height: 100%;
  width: 100%;
  display: block;
  background: red;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="upper-push">
  Scroll down
</div>
<div id="numbers">
  <span class="fig-number">25</span>
  <span class="fig-number">78</span>
</div>

答案 2 :(得分:0)

摘录:

(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 = parseInt($('.c1').text());
  var second = parseInt($('.c2').text());

  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 first-count
  $(".first-count").each(function(i, el) {
    var el = $(el);
    if (el.visible(true)) {
      countStuffUp(first, '.first-count', 1600);
    }
  });

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

});
.block {
  height: 1000px;
  background: #eeeeee;
}
.dontShow {
  //display:none;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="block">Scroll down to bottom to see counter</div>
<div>
  <span class="first-count">0</span>
  <span class="second-count">0</span>
</div>
<div class="dontShow">
  Max Value of count 1 : <span class="c1">25</span>
  <br />Max Value of count 2 : <span class="c2">78</span>
</div>

参考:Similar