检查元素在屏幕上是否可见[重复]

问题描述 投票:0回答:2

可能重复:
jQuery - 检查滚动后元素是否可见

我正在尝试确定某个元素在屏幕上是否可见。为此,我尝试使用 offsetTop 查找元素的垂直位置,但返回的值不正确。在这种情况下,除非向下滚动,否则该元素不可见。但尽管如此,当我的屏幕高度为 703 时,offsetTop 返回值 618,因此根据 offsetTop 该元素应该是可见的。

我使用的代码如下所示:

function posY(obj)
{
  var curtop = 0;

  if( obj.offsetParent )
  {
    while(1)
    {
      curtop += obj.offsetTop;

      if( !obj.offsetParent )
      {
        break;
      }

      obj = obj.offsetParent;
    }
  } else if( obj.y )
    {
     curtop += obj.y;
    }

  return curtop;
}

提前谢谢您!

javascript position offset
2个回答
172
投票

---无耻插件---
我已将此函数添加到我创建的库中 vanillajs-browser-helpershttps://github.com/Tokimon/vanillajs-browser-helpers/blob/master/src/inView.ts --------------------------------------------

路口观察者

在现代浏览器中,您可以使用 IntersectionObserver 来检测元素在屏幕上的位置或与父元素进行比较。

Intersection Observer API 提供了一种异步观察目标元素与祖先元素或顶级文档视口相交变化的方法。

今天,如果我需要检测元素何时进入或退出屏幕并做出反应,我可能会倾向于使用此 API。

但是,为了进行快速测试/查找,当您只想验证 emelemt 当前是否在屏幕上时,我会使用

getBoundingClientRect
来选择下面的版本。

使用
getBoundingClientRect

精简版

这要短得多,也应该这样做:

function checkVisible(elm) {
  var rect = elm.getBoundingClientRect();
  var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}

用小提琴来证明这一点:http://jsfiddle.net/t2L274ty/1/

加长版

还有带有

threshold
mode
的版本:

function checkVisible(elm, threshold, mode) {
  threshold = threshold || 0;
  mode = mode || 'visible';

  var rect = elm.getBoundingClientRect();
  var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  var above = rect.bottom - threshold < 0;
  var below = rect.top - viewHeight + threshold >= 0;

  return mode === 'above' ? above : (mode === 'below' ? below : !above && !below);
}

并用小提琴来证明这一点:http://jsfiddle.net/t2L274ty/2/

更传统的方法

正如 BenM 所说,您需要检测视口的高度 + 滚动位置以与顶部位置相匹配。您正在使用的功能很好并且可以完成工作,尽管它比需要的要复杂一些。

如果你不使用

jQuery
那么脚本将是这样的:

function posY(elm) {
    var test = elm, top = 0;

    while(!!test && test.tagName.toLowerCase() !== "body") {
        top += test.offsetTop;
        test = test.offsetParent;
    }

    return top;
}

function viewPortHeight() {
    var de = document.documentElement;

    if(!!window.innerWidth)
    { return window.innerHeight; }
    else if( de && !isNaN(de.clientHeight) )
    { return de.clientHeight; }
    
    return 0;
}

function scrollY() {
    if( window.pageYOffset ) { return window.pageYOffset; }
    return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}

function checkvisible( elm ) {
    var vpH = viewPortHeight(), // Viewport Height
        st = scrollY(), // Scroll Top
        y = posY(elm);
    
    return (y > (vpH + st));
}

使用 jQuery 更容易:

function checkVisible( elm, evalType ) {
    evalType = evalType || "visible";

    var vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elm).offset().top,
        elementHeight = $(elm).height();

    if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
    if (evalType === "above") return ((y < (vpH + st)));
}

这甚至提供了第二个参数。使用“visible”(或没有第二个参数)时,它会严格检查元素是否在屏幕上。如果它设置为“above”,当相关元素位于屏幕上或屏幕上方时,它将返回 true。

查看实际操作:http://jsfiddle.net/RJX5N/2/

我希望这能回答您的问题。


22
投票

你可以使用 jQuery,因为它是跨浏览器兼容的吗?

function isOnScreen(element)
{
    var curPos = element.offset();
    var curTop = curPos.top;
    var screenHeight = $(window).height();
    return (curTop > screenHeight) ? false : true;
}

然后使用类似以下内容调用该函数:

if(isOnScreen($('#myDivId'))) { /* Code here... */ };
© www.soinside.com 2019 - 2024. All rights reserved.