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

发布于 2024-10-24 08:16:02 字数 705 浏览 5 评论 0原文

可能的重复:
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;
}

提前谢谢您!

Possible Duplicate:
jQuery - Check if element is visible after scroling

I'm trying to determine if an element is visible on screen. In order to to this, I'm trying to find the element's vertical position using offsetTop, but the value returned is not correct. In this case, the element is not visible unless you scroll down. But despite of this, offsetTop returns a value of 618 when my screen height is 703, so according to offsetTop the element should be visible.

The code I'm using looks like this:

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

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫九 2024-10-31 08:16:02

--- 无耻插件 ---

我已将此函数添加到我创建的库中
@jsfns/webhttps://github.com/Tokimon/jsfns/blob/main/packages/web/src/inView.ts

----------------------------------------

Intersection Observer

在现代浏览器中,您可以使用 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/

更长的版本

以及包含 thresholdmode 的版本:

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/

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

--- Shameless plug ---

I have added this function to a library I created
@jsfns/web: https://github.com/Tokimon/jsfns/blob/main/packages/web/src/inView.ts

-------------------------------

Intersection Observer

In modern browsers you can use the IntersectionObserver which detects where an element is on the screen or compared to a parent.

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

Today I would probably lean toward this API if I need to detect and react to when an element has entered or exited the screen.

But for a quick test/lookup when you just want to verify if an emelemt is currently on screen I would go with the version just below using the getBoundingClientRect.

Using getBoundingClientRect

Short version

This is a lot shorter and should do it as well:

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

with a fiddle to prove it: http://jsfiddle.net/t2L274ty/1/

Longer version

And a version with threshold and mode included:

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

and with a fiddle to prove it: http://jsfiddle.net/t2L274ty/2/

A more traditional way to do it

As BenM stated, you need to detect the height of the viewport + the scroll position to match up with your top position. The function you are using is ok and does the job, though its a bit more complex than it needs to be.

If you don't use jQuery then the script would be something like this:

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

Using jQuery is a lot easier:

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

This even offers a second parameter. With "visible" (or no second parameter) it strictly checks whether an element is on screen. If it is set to "above" it will return true when the element in question is on or above the screen.

See in action: http://jsfiddle.net/RJX5N/2/

I hope this answers your question.

葬シ愛 2024-10-31 08:16:02

你能使用 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... */ };

Could you use jQuery, since it's cross-browser compatible?

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

And then call the function using something like:

if(isOnScreen($('#myDivId'))) { /* Code here... */ };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文