我通过AJAX加载元素。其中一些只有当你向下滚动页面时才能看到。有什么方法可以知道元素现在是否在页面的可见部分?


当前回答

function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop(),
        docViewBottom = docViewTop + $(window).height(),
        elemTop = $(elem).offset().top,
     elemBottom = elemTop + $(elem).height();
   //Is more than half of the element visible
   return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}

其他回答

我在我的应用程序中有这样一个方法,但它不使用jQuery:

/* Get the TOP position of a given element. */
function getPositionTop(element){
    var offset = 0;
    while(element) {
        offset += element["offsetTop"];
        element = element.offsetParent;
    }
    return offset;
}

/* Is a given element is visible or not? */
function isElementVisible(eltId) {
    var elt = document.getElementById(eltId);
    if (!elt) {
        // Element not found.
        return false;
    }
    // Get the top and bottom position of the given element.
    var posTop = getPositionTop(elt);
    var posBottom = posTop + elt.offsetHeight;
    // Get the top and bottom position of the *visible* part of the window.
    var visibleTop = document.body.scrollTop;
    var visibleBottom = visibleTop + document.documentElement.offsetHeight;
    return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}

编辑:此方法适用于I.E.(至少版本6)。请阅读评论以了解FF的兼容性。

使用IntersectionObserver API

(在现代浏览器中本机)


通过使用观察器来确定一个元素在视口中是否可见,或者在任何可滚动的容器中是否可见,这是非常简单有效的。

无需附加滚动事件并手动检查事件回调,这更有效:

//定义一个观察者实例 var观察者= new IntersectionObserver(onIntersection, { Root: null, // default为视口 阈值:目标可见区域的。5 //百分比。触发“onIntersection” }) //在交集变化时调用回调函数 函数onIntersection(条目,opts){ 条目。forEach(入口= > entry.target.classList。切换(“可见”,entry.isIntersecting) ) } //使用观察者来观察一个元素 观察者。观察(document.querySelector('.box')) //停止观察: / / observer.unobserve (entry.target) 跨度{:固定;上图:0;左:0;} .box{宽度:100 px;身高:100 px;背景:红色;保证金:1000 px;过渡:综合成绩;} .box。可见{背景:绿色;这个特性:50%;} <span>纵向滚动&水平…< / span > < div class = '盒子' > < / div >


现代浏览器(包括移动浏览器)支持。IE - View浏览器支持表中不支持

这是我的纯JavaScript解决方案,如果它隐藏在一个可滚动的容器。

演示在这里(尝试调整窗口的大小)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode
  // Check if bottom of the element is off the page
  if (rect.bottom < 0) return false
  // Check its within the document viewport
  if (top > document.documentElement.clientHeight) return false
  do {
    rect = el.getBoundingClientRect()
    if (top <= rect.bottom === false) return false
    // Check if the element is out of view due to a container scrolling
    if ((top + height) <= rect.top) return false
    el = el.parentNode
  } while (el != document.body)
  return true
};

编辑2016-03-26:我已经更新了解决方案,以考虑滚动过去的元素,所以它隐藏在可滚动容器的顶部。 编辑2018-10-08:更新到当滚动到屏幕上方的视图外时处理。

制作了一个简单的插件,用于检测元素在可滚动容器中是否可见

    $.fn.isVisible = function(){

      var win;
      if(!arguments[0])
      {
        console.error('Specify a target;');
        return false;
      }
      else
      {
        win = $(arguments[0]);
      }
      var viewport = {};
      var bounds = this.offset();
      bounds.right = bounds.left + this.outerWidth();
      bounds.bottom = bounds.top + this.outerHeight();
      viewport.bottom = win.height() + win.offset().top;
      return (!( bounds.top > viewport.bottom) && (win.offset().top < bounds.bottom));
    };

像这样调用$('elem_to_check').isVisible('scrollable_container');

希望能有所帮助。

更新:使用IntersectionObserver


目前为止我发现的最好的方法是jQuery appear插件。效果非常好。

模仿自定义的“appear”事件,该事件在元素滚动到视图或以其他方式对用户可见时触发。 $ (' # foo) .appear(函数(){ (美元)。文本(“Hello world”); }); 这个插件可以用来防止对隐藏的或在可视区域之外的内容的不必要请求。