2011-03-18 80 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