开发者问题收集

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

2009-01-28
936060

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

3个回答

这应该可以解决问题:

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');
}
Scott Dowding
2009-01-28

此答案 (Vanilla 版):

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;
}
korywka
2014-03-18

使用 IntersectionObserver API

(现代浏览器原生)


使用 observer 可以轻松高效地确定元素在视口或任何可滚动容器中是否可见。

无需附加 scroll 事件并手动检查事件回调,效率更高:

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: .5 // percentage of target'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 observer 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 不支持此功能 - 查看浏览器支持表

vsync
2017-08-10