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


当前回答

这个问题有超过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!

其他回答

修改了已接受的答案,以便元素必须将其display属性设置为“none”以外的值,以便质量为可见。

function isScrolledIntoView(elem) {
   var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();
  var elemDisplayNotNone = $(elem).css("display") !== "none";

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
}

我更喜欢使用jQuery expr

jQuery.extend(jQuery.expr[':'], {  
    inview: function (elem) {
        var t = $(elem);
        var offset = t.offset();
        var win = $(window); 
        var winST = win.scrollTop();
        var elHeight = t.outerHeight(true);

        if ( offset.top > winST - elHeight && offset.top < winST + elHeight + win.height()) {
            return true;    
        }    
        return false;  
    }
});

你可以这样用

$(".my-elem:inview"); //returns only element that is in view
$(".my-elem").is(":inview"); //check if element is in view
$(".my-elem:inview").length; //check how many elements are in view

你可以很容易地在滚动事件函数中添加这样的代码等,以检查它每次用户将滚动视图。

检查元素是否在屏幕上,而不是公认的检查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);
}

在打印稿

  private readonly isElementInViewPort = (el: HTMLElement): boolean => {
      const rect = el.getBoundingClientRect();
      const elementTop = rect.top;
      const elementBottom = rect.bottom;
      const scrollPosition = el?.scrollTop || document.body.scrollTop;
      return (
        elementBottom >= 0 &&
        elementTop <= document.documentElement.clientHeight &&
        elementTop + rect.height > elementTop &&
        elementTop <= elementBottom &&
        elementTop >= scrollPosition
      );

};

简单的检查元素(el)是否在可滚动的div (holder)中可见

function isElementVisible (el, holder) {
  holder = holder || document.body
  const { top, bottom, height } = el.getBoundingClientRect()
  const holderRect = holder.getBoundingClientRect()

  return top <= holderRect.top
    ? holderRect.top - top <= height
    : bottom - holderRect.bottom <= height
}

使用jQuery:

var el = $('tr:last').get(0);
var holder = $('table').get(0);
var isVisible = isElementVisible(el, holder);