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


当前回答

检查元素是否在屏幕上,而不是公认的检查div是否完全在屏幕上的方法(如果div比屏幕大,这将不起作用)。在纯Javascript中:

/**
 * Checks if element is on the screen (Y axis only), returning true
 * even if the element is only partially on screen.
 *
 * @param element
 * @returns {boolean}
 */
function isOnScreenY(element) {
    var screen_top_position = window.scrollY;
    var screen_bottom_position = screen_top_position + window.innerHeight;

    var element_top_position = element.offsetTop;
    var element_bottom_position = element_top_position + element.offsetHeight;

    return (inRange(element_top_position, screen_top_position, screen_bottom_position)
    || inRange(element_bottom_position, screen_top_position, screen_bottom_position));
}

/**
 * Checks if x is in range (in-between) the
 * value of a and b (in that order). Also returns true
 * if equal to either value.
 *
 * @param x
 * @param a
 * @param b
 * @returns {boolean}
 */
function inRange(x, a, b) {
    return (x >= a && x <= b);
}

其他回答

我改编了这个简短的jQuery函数扩展,你可以自由使用(MIT许可)。

/**
 * returns true if an element is visible, with decent performance
 * @param [scope] scope of the render-window instance; default: window
 * @returns {boolean}
 */
jQuery.fn.isOnScreen = function(scope){
    var element = this;
    if(!element){
        return;
    }
    var target = $(element);
    if(target.is(':visible') == false){
        return false;
    }
    scope = $(scope || window);
    var top = scope.scrollTop();
    var bot = top + scope.height();
    var elTop = target.offset().top;
    var elBot = elTop + target.height();

    return ((elBot <= bot) && (elTop >= top));
};

这里有另一个解决方案:

<script type="text/javascript">
$.fn.is_on_screen = function(){
    var win = $(window);
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right ||    viewport.bottom < bounds.top || viewport.top > bounds.bottom));
 };

if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info       
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
$(window).on('scroll', function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
});
</script>

在JSFiddle中可以看到

这应该可以达到目的:

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

jquery scrollspy插件将允许您轻松做到这一点。 https://github.com/thesmart/jquery-scrollspy

$('.tile').on('scrollSpy:enter', function() {
    console.log('enter:', $(this).attr('id'));
});

$('.tile').on('scrollSpy:exit', function() {
    console.log('exit:', $(this).attr('id'));
});

$('.tile').scrollSpy();

使用IntersectionObserver API

(在现代浏览器中本机)


通过使用观察器来确定一个元素在视口中是否可见,或者在任何可滚动的容器中是否可见,这是非常简单有效的。

无需附加滚动事件并手动检查事件回调,这更有效:

//定义一个观察者实例 var观察者= new IntersectionObserver(onIntersection, { Root: null, // default为视口 阈值:目标可见区域的。5 //百分比。触发“onIntersection” }) //在交集变化时调用回调函数 函数onIntersection(条目,opts){ 条目。forEach(入口= > entry.target.classList。切换(“可见”,entry.isIntersecting) ) } //使用观察者来观察一个元素 观察者。观察(document.querySelector('.box')) //停止观察: / / observer.unobserve (entry.target) 跨度{:固定;上图:0;左:0;} .box{宽度:100 px;身高:100 px;背景:红色;保证金:1000 px;过渡:综合成绩;} .box。可见{背景:绿色;这个特性:50%;} <span>纵向滚动&水平…< / span > < div class = '盒子' > < / div >


现代浏览器(包括移动浏览器)支持。IE - View浏览器支持表中不支持