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


当前回答

这里的大多数答案都没有考虑到一个元素也可以被隐藏,因为它被滚动出div的视图,而不仅仅是整个页面。

为了排除这种可能性,基本上必须检查元素是否位于其每个父元素的边界内。

这个解决方案正是这样做的:

function(element, percentX, percentY){
    var tolerance = 0.01;   //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
    if(percentX == null){
        percentX = 100;
    }
    if(percentY == null){
        percentY = 100;
    }

    var elementRect = element.getBoundingClientRect();
    var parentRects = [];

    while(element.parentElement != null){
        parentRects.push(element.parentElement.getBoundingClientRect());
        element = element.parentElement;
    }

    var visibleInAllParents = parentRects.every(function(parentRect){
        var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
        var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
        var visiblePercentageX = visiblePixelX / elementRect.width * 100;
        var visiblePercentageY = visiblePixelY / elementRect.height * 100;
        return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
    });
    return visibleInAllParents;
};

它还允许您指定在每个方向上必须可见的百分比。 它不包括由于其他因素(如display: hidden)而隐藏的可能性。

这应该适用于所有主流浏览器,因为它只使用getBoundingClientRect。我个人在Chrome和Internet Explorer 11上测试了它。

其他回答

更新:使用IntersectionObserver


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

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

jQuery Waypoints插件在这里做得非常好。

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

在插件的站点上有一些例子。

在毫无成效地跑来跑去并使用了几个不工作的代码之后。这就是我使用Jquery实现垂直滚动可视性的方法。 将'#footerplace'替换为您想垂直跟踪的元素。

jQuery.expr.filters.offscreen = function(el) {
  var rect = el.getBoundingClientRect();
  console.log(rect)
  console.log('window height', $(window).height());

  return (
           (rect.top <= $(window).height()) && (rect.bottom <= $(window).height())
         );
};
$(document).scroll(function(){
    if ($('#footerplace').is(':offscreen')){
      console.log('this is true');
    $('#footerplace').is(':offscreen');
    } else {
     console.log('this is false');
    $('#footerplace').is(':offscreen');

    }
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));
}

我只是想分享一下,我把这个和我的脚本结合起来移动div,这样它就总是在视图中:

    $("#accordion").on('click', '.subLink', function(){
        var url = $(this).attr('src');
        updateFrame(url);
        scrollIntoView();
    });

    $(window).scroll(function(){
            changePos();
    });

  function scrollIntoView()
  {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();    
        var elemTop = $("#divPos").offset().top;
        var elemBottom = elemTop + $("#divPos").height();               
        if (elemTop < docViewTop){
            $("#divPos").offset({top:docViewTop});
        }
   }

   function changePos(){        
    var scrTop = $(window).scrollTop();
    var frmHeight = $("#divPos").height()
        if ((scrTop < 200) || (frmHeight > 800)){   
         $("#divPos").attr("style","position:absolute;");
        }else{
          $("#divPos").attr("style","position:fixed;top:5px;");
        }
    }