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


当前回答

jQuery有一个名为inview的插件,它添加了一个新的inview事件。


下面是jQuery插件不使用事件的代码:

$.extend($.expr[':'],{
    inView: function(a) {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
            ot = $(a).offset().top,
            wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
        return ot > st && ($(a).height() + ot) < (st + wh);
    }
});

(function( $ ) {
    $.fn.inView = function() {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
        ot = $(this).offset().top,
        wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();

        return ot > st && ($(this).height() + ot) < (st + wh);
    };
})( jQuery );

我在一个叫James的家伙的评论中发现了这一点(http://remysharp.com/2009/01/26/element-in-view-event-plugin/)

其他回答

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

    $.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');

希望能有所帮助。

这里有另一个解决方案:

<script type="text/javascript">
$.fn.is_on_screen = function(){
    var win = $(window);
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right ||    viewport.bottom < bounds.top || viewport.top > bounds.bottom));
 };

if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info       
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
$(window).on('scroll', function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
});
</script>

在JSFiddle中可以看到

唯一适用于我的解决方案是(当$("#elementToCheck")可见时返回true):

$ (document) .scrollTop () + window.innerHeight + $ (" # elementToCheck ") .height () > $ (" # elementToCheck ") .offset直()上

我在我的应用程序中有这样一个方法,但它不使用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的兼容性。

在这个伟大答案的基础上,你可以使用ES2015+进一步简化它:

function isScrolledIntoView(el) {
  const { top, bottom } = el.getBoundingClientRect()
  return top >= 0 && bottom <= window.innerHeight
}

如果你不关心顶部是否跳出窗口而只关心底部是否被看到,这可以简化为

function isSeen(el) {
  return el.getBoundingClientRect().bottom <= window.innerHeight
}

或者甚至是单行语句

const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight