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


当前回答

我改编了这个简短的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));
};

其他回答

我正在寻找一种方法来查看元素是否即将进入视图,所以通过扩展上面的代码段,我设法做到了。我想我应该把这个留在这里,说不定能帮到谁

Elm =是视图中要检查的元素

scrollElement =你可以传递window或者带有滚动的父元素

Offset =如果你想让它在元素在屏幕前200px处触发,那么传递200

isscro冷景的功能(elem, scrole,抵消) { var $elem = $(elem); var $window = $); var docViewTop = $window.scrollTop(); var docViewBottom = docViewTop + $window.height(); var elemTop = $elem.抵消()top; var elemBottom = elemTop + $elem.height() 归来((elemBottom +) > = docViewBottom) &&偏移(elemTop-offset) < = docViewTop) | | ((elemBottom-offset) < = docViewBottom) && (elemTop +偏移)> = docViewTop); 的

我找到的最简单的解决方案是交集观察者API:

var observer = new IntersectionObserver(function(entries) {
    if(entries[0].isIntersecting === true)
        console.log('Element has just become visible in screen');
}, { threshold: [0] });

observer.observe(document.querySelector("#main-container"));

这个问题有超过30个答案,没有一个使用我一直在使用的令人惊讶的简单的纯JS解决方案。没有必要仅仅为了解决这个问题而加载jQuery,因为许多人都在推动这个问题。

为了判断元素是否在视口中,我们必须首先确定元素在主体中的位置。我们不需要像我以前想的那样递归地做这个。相反,我们可以使用element.getBoundingClientRect()。

pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;

这个值是物体顶部和主体顶部之间的Y差。

然后我们必须判断元素是否在视图中。大多数实现都会询问完整的元素是否在视口中,所以这就是我们将要讨论的内容。

首先,窗口的顶部位置是:window. scrolly。

我们可以通过将窗口的高度加到窗口的顶部位置来获得窗口的底部位置:

var window_bottom_position = window.scrollY + window.innerHeight;

让我们创建一个简单的函数来获取元素的顶部位置:

function getElementWindowTop(elem){
    return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}

这个函数将返回元素在窗口中的顶部位置,或者如果你通过. getboundingclientrect()方法传递给它的不是元素,它将返回0。这个方法已经存在很长时间了,所以您不必担心浏览器不支持它。

现在,元素的顶部位置是:

var element_top_position = getElementWindowTop(element);

And或元素的底部位置为:

var element_bottom_position = element_top_position + element.clientHeight;

现在我们可以通过检查元素的底部位置是否低于viewport的顶部位置,以及检查元素的顶部位置是否高于viewport的底部位置来确定元素是否在viewport中:

if(element_bottom_position >= window.scrollY 
&& element_top_position <= window_bottom_position){
    //element is in view
else
    //element is not in view

从那里,您可以执行逻辑来在元素上添加或删除视图内类,然后您可以稍后在CSS中使用过渡效果处理该类。

我非常惊讶,我没有在其他地方找到这个解决方案,但我相信这是最干净和最有效的解决方案,而且它不需要您加载jQuery!

制作了一个简单的插件,用于检测元素在可滚动容器中是否可见

    $.fn.isVisible = function(){

      var win;
      if(!arguments[0])
      {
        console.error('Specify a target;');
        return false;
      }
      else
      {
        win = $(arguments[0]);
      }
      var viewport = {};
      var bounds = this.offset();
      bounds.right = bounds.left + this.outerWidth();
      bounds.bottom = bounds.top + this.outerHeight();
      viewport.bottom = win.height() + win.offset().top;
      return (!( bounds.top > viewport.bottom) && (win.offset().top < bounds.bottom));
    };

像这样调用$('elem_to_check').isVisible('scrollable_container');

希望能有所帮助。

这个答案的一个更有效的版本:

 /**
 * Is element within visible region of a scrollable container
 * @param {HTMLElement} el - element to test
 * @returns {boolean} true if within visible region, otherwise false
 */
 function isScrolledIntoView(el) {
      var rect = el.getBoundingClientRect();
      return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
 }