题 滚动后检查元素是否可见


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


977
2018-01-28 10:00


起源


我真的不明白这个问题。你能尝试添加更多信息吗? - Natrium
他的意思是他想要一个方法来知道给定元素是否显示在浏览器窗口中,或者用户是否需要滚动才能看到它。 - romaintaz
要检查元素是否在容器中完全可见,只需添加一个额外的选择器参数并重新使用它的elem代码。 Library.IsElementVisibleInContainer = function (elementSelector, containerSelector) { var containerViewTop = $(containerSelector).offset().top; var containerViewBottom = containerViewTop + $(containerSelector).height(); - Lifes
什么是这个“图书馆”@Lindsay? - periback2
可能重复 如何判断DOM元素在当前视口中是否可见? - h22


答案:


这应该是诀窍:

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

1134
2018-01-28 15:36



请注意,这仅在文档是滚动元素时才有效,即您没有检查滚动内部窗格中某些元素的可见性。 - Andrew Badr
如何添加一点偏移量? - Jürgen Paul
只有在我使用时才有效 window.innerHeight 代替 - Christian Schnorr
对于 elemTop 我用了 $(elem).position().top 并为 elemBottom 我用了 elemTop + $(elem).outerHeight(true)。 - Sarah Vessels
对于:“视图中元素的任何部分”,我使用:(((elemTop> = docViewTop)&&(elemTop <= docViewBottom))||((elemBottom> = docViewTop)&&(elemBottom <= docViewBottom))) - Grizly


这个答案 在香草:

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

297
2018-03-18 13:31



不应该这样 isVisible = elementTop < window.innerHeight && elementBottom >= 0?否则,屏幕上的元素一半返回false。 - gman
没有。我检查一些元素是否在页面上完全可见。如果您想检查某个部分的可见性 - 您可以自定义此代码段。 - bravedick
我发现这个答案比选择的答案表现得更好。也更简单。 - Adam Venezia
与批准的答案相比,这可以使用数百个元素更好地执行。 - ncla
看到这里展示的小提琴 - jsfiddle.net/shaaraddalvi/4rp09jL0 - upInCloud


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

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

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

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


113
2017-08-20 21:31



毫无疑问,这是一个很酷的插件,但没有回答这个问题。 - Jon Adams
虽然jQuery-appear插件适用于主页面区域的内容,但遗憾的是它存在固定大小滚动div与溢出问题。当绑定元素位于页面的可查看区域内但在div的可查看区域之外时,事件可能会过早触发,然后当元素进入div中的视图时,不会按预期触发。 - Peter
是否有一个消失的插件? - Shamoon
@Shamoon检查来源了 appear plugin 你可能只需要添加一个 ! 某个地方得到一个 disappear 插入。 - Lucky Soni
请注意,这不适用于jQuery 1.11.X github.com/morr/jquery.appear/issues/37 - Jason Parham


这是我的纯JavaScript解决方案,如果它也隐藏在可滚动容器中,它也可以工作。

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

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode;
  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);
  // Check its within the document viewport
  return top <= document.documentElement.clientHeight;
};

编辑2016-03-26:我已经更新了解决方案,以便滚动浏览元素,因此它隐藏在可滚动容器的顶部之上。


65
2018-02-07 12:02



谢谢,也许更好 return top <= document.documentElement.clientHeight && top >= 0; - Yousef Salimpour
+1这是考虑到元素的递归性质的唯一编码(即非第三方)答案。我已经扩展到处理水平,垂直和页面滚动: jsfiddle.net/9nuqpgqa - Pebbl
感谢纯JS解决方案 - Frederic Fortier
此解决方案仅检查元素的顶部。如果第一个顶部像素可见,即使项目的其余部分不可见,它也会返回true。要检查整个元素是否可见,您还需要检查底部属性。 - Wojciech Jakubas
是的,整洁!用来帮忙写 这个答案 (作为js评论的信用)。 - Roamer-1888


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

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

有一些例子 插件的网站


40
2017-12-04 12:08



对我来说,它只适用于偏移量 $('#my-div').waypoint(function() { console.log('Hello there!'); }, { offset: '100%' }); - leymannx


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

14
2018-01-28 14:14





怎么样

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

之后,一旦元素在视图中,你可以触发你想要的任何东西

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

这对我很有用


14
2018-04-29 10:24



这适用于我,但我使用了看似更完整的函数isScrolledIntoView at stackoverflow.com/questions/487073/... :) - Meetai.com
我认为它应该是$(window).scrollTop()<$(elem).offset()。top + $(elem).height(); - Young


根据我的要求,Scott Dowding的功能很酷 - 这用于查找元素是否刚刚滚动到屏幕中,即它的上边缘。

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

12
2018-04-30 16:08