检查元素是否在屏幕上可见

Rob*_*ert 66 javascript position offset

可能重复:
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;
}
Run Code Online (Sandbox Code Playgroud)

先感谢您!

Tok*_*mon 118

BenM说,你需要检测视口的高度+滚动位置以匹配你的顶部poisiton.你使用的功能还可以完成工作,尽管它的功能更加复杂.

如果你不使用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));
}
Run Code Online (Sandbox Code Playgroud)

使用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)));
}
Run Code Online (Sandbox Code Playgroud)

这甚至提供了第二个参数.使用"可见"(或没有第二个参数)时,它会严格检查元素是否在屏幕上.如果它设置为"高于",则当有问题的元素位于屏幕上或屏幕上方时,它将返回true.

见作者:http://jsfiddle.net/RJX5N/2/

我希望这回答了你的问题.

- 改良版 -

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

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

用小提琴来证明它: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);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 使用正确命名的变量比使用带有注释的钝命名变量要好得多! (8认同)
  • 检查整个元素是否可见:`function checkvisible(elm){var vpH = $(window).height(),// Viewport Height st = $(window).scrollTop(),// Scroll Top y = $( elm).offset().top,h = $(elm).height(); return(y> st && y + h <(vpH + st)); 检查元素的任何部分是否可见:`function checkvisible(elm){var vpH = $(window).height(),// Viewport Height st = $(window).scrollTop(),// Scroll Top y = $(elm).offset().top,h = $(elm).height(); return(y + h> st && y <(vpH + st)); }` (4认同)
  • 对于jQuery条件应该改为`(y> st)&&(y <(vpH + st))`**OO**`(y + $(elm).height()<st + vpH)`其中**OO**是"||"用于部分可见性,"&&"用于完全可见性. (3认同)
  • @SuperUberDuper,再次`getBoundingClientRect()`是你的朋友.如果它或它的一个祖先显示为none,它将返回设置为0(零)的属性. (2认同)

Ben*_*enM 17

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

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

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

if(isOnScreen($('#myDivId'))) { /* Code here... */ };
Run Code Online (Sandbox Code Playgroud)

  • 为什么不返回`!(curTop> screenHeight)`?? (8认同)
  • 你可以做,但我个人认为上面的代码更具可读性. (5认同)
  • @BenM 我可以让它更不可读!返回 !(element.offset().top &gt; $(window).height()); (2认同)
  • 但是我会对此进行投票,因为它很容易理解.如果你改变`var curTop = curPos.top - $(window).scrollTop();它会有效. (2认同)