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

IT技术 javascript jquery scroll
2020-12-12 01:03:18

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

6个回答

这应该可以解决问题:

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');
}
这工作得很好,当该元素是打开的文档中,这给了不合适的结果时使用了一些元素师滚动里面,我试图取代$(window)$("somediv")还没有精确的结果,我怎么能得到这个准确的结果?
2021-02-08 01:03:18
对于:“视图中元素的任何部分”,我使用了:(((elemTop >= docViewTop) && (elemTop <= docViewBottom)) || ((elemBottom >= docViewTop) && (elemBottom <= docViewBottom)))
2021-02-16 01:03:18
请注意,这仅在文档是正在滚动的元素时才有效,即您没有检查滚动内部窗格内某些元素的可见性。
2021-02-26 01:03:18

香草中的这个答案

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;
}
我发现这个答案比选择的答案表现更好。也比较简单。
2021-02-23 01:03:18
不。我检查某些元素是否在页面上完全可见。如果您想检查某个部分的可见性 - 您可以自定义此代码段。
2021-02-24 01:03:18
与批准的答案相比,这在数百个元素中的表现要好得多。
2021-02-24 01:03:18
这不应该是isVisible = elementTop < window.innerHeight && elementBottom >= 0吗?否则屏幕上的一半元素返回 false。
2021-03-09 01:03:18

更新:使用IntersectionObserver


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

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

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

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

有消失插件吗?
2021-02-20 01:03:18
毫无疑问,这是一个很酷的插件,但没有回答问题。
2021-02-24 01:03:18

使用IntersectionObserver API

(原生于现代浏览器)


使用观察者可以轻松有效地确定元素在视口或任何可滚动容器中是否可见

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

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: .5 // percentage of taregt's visible area. Triggers "onIntersection"
})

// callback is called on intersection change
function onIntersection(entries, opts){
  entries.forEach(entry =>  
    entry.target.classList.toggle('visible', entry.isIntersecting)
  )
}

// Use the bserver to observe an element
observer.observe( document.querySelector('.box') )

// To stop observing:
// observer.unobserve(entry.target)
span{ position:fixed; top:0; left:0; }
.box{ width:100px; height:100px; background:red; margin:1000px; transition:.75s; }
.box.visible{ background:green; border-radius:50%; }
<span>Scroll both Vertically &amp; Horizontally...</span>
<div class='box'></div>


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

这是我的纯 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:更新为在屏幕上方滚动出视图时处理。

+1 这是唯一考虑到元素递归性质的编码(即非第三方)答案。我已经扩展到处理水平、垂直和页面滚动:jsfiddle.net/9nuqpgqa
2021-02-14 01:03:18