滚动后如何检查元素是否可见?

我正在通过 AJAX 加载元素。仅当您向下滚动页面时,其中一些才可见。
我有什么办法可以知道某个元素是否现在在页面的可见部分中?

答案

这应该可以解决问题:

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

简单实用程序功能这将允许您调用一个实用程序功能,该功能接受您要查找的元素,以及您是否希望该元素完全可见或部分可见。

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

用法

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
    console.log('in view');
} else {
    console.log('out of view');
}

香草的答案

function isScrolledIntoView(el) {
    var rect = el.getBoundingClientRect();
    var elemTop = rect.top;
    var elemBottom = rect.bottom;

    // Only completely visible elements return true:
    var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
    // Partially visible elements return true:
    //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
    return isVisible;
}

更新:使用IntersectionObserver


到目前为止,我发现的最好的方法是jQuery 出现插件 。奇迹般有效。

模仿一个自定义的 “出现” 事件,该事件在元素滚动到视图中或以其他方式对用户可见时触发。

$('#foo').appear(function() {
  $(this).text('Hello world');
});

该插件可用于防止对隐藏或可见区域之外的内容进行不必要的请求。

这是我的纯 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
};

EDIT 2016-03-26:我已经更新了解决方案,以解决滚动到元素上方的问题,因此该元素隐藏在可滚动容器顶部的上方。 EDIT 2018-10-08:更新为在屏幕上方滚动出视图时进行处理。

jQuery Waypoints 插件在这里非常好用。

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

插件站点上有一些示例。

使用IntersectionObserver API(现代浏览器中的本机)

通过使用观察者 ,可以轻松高效地确定元素在 viewpor 或任何可滚动容器中是否可见。

消除了附加scroll事件和手动检查事件回调的需要,从而提高了效率:

// this is the target which is observed
var target = document.querySelector('div');

// configure the intersection observer instance
var intersectionObserverOptions = {
  root: null,
  rootMargin: '150px',
  threshold: 1.0
}
    
var observer = new IntersectionObserver(onIntersection, intersectionObserverOptions);

// provide the observer with a target
observer.observe(target);

function onIntersection(entries){
  entries.forEach(entry => {
    console.clear();
    console.log(entry.intersectionRatio)
    target.classList.toggle('visible', entry.intersectionRatio > 0);
    
    // Are we in viewport?
    if (entry.intersectionRatio > 0) {
      // Stop watching 
      // observer.unobserve(entry.target);
    }
  });
}
.box{ width:100px; height:100px; background:red; margin:1000px; }
.box.visible{ background:green; }
Scroll both Vertically & Horizontally...
<div class='box'></div>


查看浏览器支持表 (IE / Safari 中不支持)

怎么样

function isInView(elem){
   return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}

之后,一旦元素出现在视图中,您就可以触发所需的任何操作

$(window).scroll(function(){
   if (isInView($('.classOfDivToCheck')))
      //fire whatever you what 
      dothis();
})

对我来说很好

WebResourcesDepot编写了一个脚本,该脚本在一段时间前使用jQuery 进行滚动加载 。您可以在此处查看他们的现场演示 。他们功能的主要部分是:

$(window).scroll(function(){
  if  ($(window).scrollTop() == $(document).height() - $(window).height()){
    lastAddedLiveFunc();
  }
});

function lastAddedLiveFunc() { 
  $('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
  $.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
    function(data){
        if (data != "") {
          $(".wrdLatest:last").after(data);         
        }
      $('div#lastPostsLoader').empty();
    });
};

对于我的需求,Tweeked 的 Scott Dowding 很酷的功能 - 用于查找元素是否刚刚滚动到屏幕(即它的顶部边缘)中。

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}

isScrolledIntoView是一个非常需要的函数,因此我尝试了它,它适用于不比视口高的元素,但是如果该元素较大,则视口不起作用。要解决此问题,请轻松更改条件

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

对此:

return (docViewBottom >= elemTop && docViewTop <= elemBottom);

在此处查看演示: http : //jsfiddle.net/RRSmQ/