如何计算 50% 的元素是否在视口中?

How to calculate if 50% of element is in viewport?

我目前正在使用 getBoundingClientRect() 来计算元素是否进入视口。不过,我真正需要做的是检查元素的 50%(或任何给定百分比)是否已进入视口(我正在检查滚动)。如果它可见,那么我会更新页面上的一些文本说是,如果它不可见,那么文本会说不。

我似乎无法理解逻辑,它开始让我发疯,有人能帮忙吗?

当前代码如下!

isBannerInView: function (el, y) {
  var _this = this,
    elemTop,
    elemBottom,
    elemHeight,
    isVisible;

  for (var i = 0; i < el.length; i++) {
    var pos = banners.indexOf(el[i]);

    elemTop = el[i].getBoundingClientRect().top;
    elemBottom = el[i].getBoundingClientRect().bottom;
    elemHeight = el[i].getBoundingClientRect().height;

    isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);

    _this.updateResults(el[i], pos, isVisible);
  };
},

updateResults: function (el, pos, isVisible) {
  var isInView = isVisible ? 'Yes' : 'No';

  document.querySelectorAll('.results')[0].getElementsByTagName('span')[pos].innerHTML = isInView;
},

jsBin demo

/**
 * inViewport jQuery plugin by Roko C.B. whosebug.com/questions/24768795/
 *
 * Returns a callback function with an argument holding
 * the current amount of px an element is visible in viewport
 * (The min returned value is 0 (element outside of viewport)
 * The max returned value is the element height + borders)
 */
;(function($, win) {
  $.fn.inViewport = function(cb) {
     return this.each(function(i,el) {
       function visPx(){
         var elH = $(el).outerHeight(),
             H = $(win).height(),
             r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
         return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : (b<H?b:H)));  
       }
       visPx();
       $(win).on("resize scroll", visPx);
     });
  };
}(jQuery, window));



$("#banner").inViewport(function( px ){
  var h = $(this).height();
  var isHalfVisible =  px >= h/2;
  $(this).css({background: isHalfVisible?"green":"red"});
});
#banner{
  height:600px;
  background:red;
  margin:1500px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="banner">I'll turn GREEN when I'm more than 50% in viewport</div>

所以插件取自
P.S:由于侦听 scroll 事件非常昂贵,您可能希望在代码中添加一个事件 Throttle/Debounce 延迟方法。