2011-03-18 85 views
45

Possible Duplicate:
jQuery - Check if element is visible after scroling检查元素在屏幕上

可见我试图确定元素是否显示在屏幕上。为了达到这个目的,我试图使用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; 
} 

预先感谢您!

+0

你试过用'top'代替offsetTop吗? – Neal 2011-03-18 15:16:57

+0

检出:http://stackoverflow.com/questions/487073/jquery-check-if-element-is-visible-after-scroling – RDL 2011-03-18 15:28:17

回答

0

然后,您想使用scrollTop将元素顶部位置与页面进行比较。

+1

实际上,':visible'选择器只检查它是否实际呈现,而不是如果它符合浏览器视口的范围。 – BenM 2011-03-18 15:19:42

+0

这是行不通的。http://api.jquery.com/visible-selector – 2011-03-18 15:21:11

+0

啊,是的,抱歉错过阅读的问题。你想scrollTop()用来比较元素的位置。 – RDL 2011-03-18 15:25:01

15

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

if(isOnScreen($('#myDivId'))) { /* Code here... */ }; 
+0

我尝试这段代码,但是我从这行中得到了这个错误'Uncaught SyntaxError:Unexpected token return'(curTop> screenHeight)?返回false:返回true; ' – gadss 2012-10-24 10:01:27

+1

我编辑了代码,它现在应该可以运行。 – BenM 2012-10-24 11:57:43

+7

为什么不返回'!(curTop> screenHeight)'? – Giann 2013-02-06 09:22:37

86

好BenM说,你需要检测视+滚动位置的高度,用你最poisiton匹配:

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

,然后使用类似调用该函数。你使用的功能是好的,做这项工作,尽管它需要更复杂的运动。

如果你不使用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))); 
} 

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

见行动:http://jsfiddle.net/RJX5N/2/

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

- 改进VERSION--

这是短了很多,应该做得一样好:用小提琴

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/

+0

问题仍然是最初的Y值是618,但只要我开始滚动Y值更改为1074,这是元素的正确Y值。为什么是这样? – Robert 2011-03-18 23:19:28

+1

@罗伯特:这听起来很奇怪!你在那个元素之前插入了什么元素?或者你重新定位它?但是,我的脚本中的'(vpH + st)'部分应该增加,如果那就是你想知道的。 – Tokimon 2011-03-20 15:49:12

+3

对于jQuery条件应该用'(y> st)&&(y <(vpH + st))** **(y + $(elm).height() 2013-04-22 10:01:10