2008-12-09 12 views
11

當使用Google閱讀器並在「擴展」視圖中瀏覽RSS條目時,一旦屏幕上可見div的某個百分比,條目將自動標記爲「讀取」(難以確定在屏幕上可見的百分比谷歌閱讀器的情況)。因此,當我逐行滾動時,javascript代碼可以確定a)條目正在可見窗口中呈現,並且b)一定量可見,並且當滿足這些條件時,狀態被切換爲讀取。檢測窗口中顯示的div以實現Google-Reader-like-auto-mark-as-read?

有沒有人有任何想法如何實現該功能?具體來說,有沒有人知道如何知道div是否滾動查看div的多少可見?另外,我使用jQuery,所以如果任何人有任何jQuery特定的例子,他們將不勝感激。

回答

4

真正的技巧是跟蹤滾動條在包含項目的元素中的位置。以下是我曾經鞭撻過的一些代碼:http://pastebin.com/f4a329cd9

您可以看到,當您滾動時,它會改變焦點。您只需將更多的處理程序代碼添加到處理每個焦點更改的函數中。它可以在兩個方向上滾動,也可以在滾動條上單擊鼠標右鍵,這種簡單的鼠標跟蹤不會給你(儘管在這種情況下,由於示例元素大小相同,文本相同,所以很難說它確實滾動了)。另一個問題是容器底部出現時應該怎麼做。我現在的解決方案只適用於FF。如果你想在IE中看起來不錯,你將不得不使用一個虛擬元素混合到背景中,就像我在代碼中註釋過的那樣。

0

根據我的經驗,如果我對它進行了更改或點擊,Reader只會標記爲已讀。假設當你滾動你的鼠標在div上時(當我滾動時,我傾向於將鼠標放到屏幕的右邊緣),這可能解釋了只有在顯示特定百分比時它纔會被標記掉的外觀。

雖然我可能(可能是)錯了。我只知道在閱讀器中滾動瀏覽項目的行爲並不能標記出來。我必須確保鼠標在鼠標上滾動才能滾動。

+0

這是一個有趣的假設,所以這次我非常小心避免進入任何內容。我從滾動下拉按鈕開始,然後圍繞窗口外側,然後下降到允許我在展開/列表視圖之間切換的區域,並將條目標記爲已讀。 – smoody 2008-12-09 20:53:13

0

該dom和JavaScript讓你計算從它的父母的元素偏移量。要計算窗口的偏移量,您需要使用遞歸併爬上頂部窗口,並將其與窗口大小進行比較。由於跨瀏覽器問題和iframe,它變得更加複雜。

據我所知,原型提供了一個簡單的viewportOffset方法,爲您完成大部分工作。您還可以檢查來源getOffsetParentscrollTo。我不知道jquery,但我期望它提供類似的方法。

我的猜測是,谷歌閱讀器中的腳本只是運行在超時,可能每秒幾次,或者可能是爲了響應滾動事件。在這兩種情況下,我都確定它是自適應的(基於用戶滾動的速度等等,超時更改),並且它足夠聰明,不會成爲資源管理員(即,不要只檢查所有的div文檔)

0

爲了計算的元素是否是可見的,你可以創建這樣的功能(信用由於這裏https://stackoverflow.com/a/22480938/825240):

function isScrolledIntoView(element) { 
    var elementTop = element.getBoundingRect().top; 
    var elementBottom = element.getBoundingRect().bottom; 

    var isVisible = (elementTop <= window.innerHeight) && (elementBottom >= 0); 
    return isVisible; 
} 

您可以通過元素是否已被讀取計算自定義功能,根據您的情況:

function isRead(element) { 
    var elementTop = element.getBoundingRect().top; 
    var elementBottom = element.getBoundingRect().bottom; 
    var elementHeight = elementBottom - elementTop; 

    // if 75% of the document has been scrolled, we'll assume it's been read 
    var readIfPercentage = 0.75; 

    // an element has been read if the top has been scrolled up out of view 
    // and at least 75% of the element is no longer visible 
    var isRead = (elementTop < 0 && Math.abs(elementTop)/elementHeight >= readIfPercentage); 
    return isRead; 
} 

然後可以調用上述的功能,在DOM節點傳遞作爲元件:

isScrolledIntoView(document.getElementById('targetDiv'); 
//or 
isRead(document.getElementById('targetDiv'); 

可以通過創建一個滾動聽者將其結合在一起(jQuery讓這很容易):

function setScrollListener() { 

    var scrollEventHandler = function() { 
    if (isRead(document.getElementById('article'))) { 
     // set article to 'read' 
    } 
    } 

    // on scroll, fire the event handler 
    $(document).scroll(scrollEventHandler); 
} 

值得注意的是,如果你想解除滾動監聽器的綁定,比如說如果所有的文章都被讀取了,而你不再需要監聽滾動文件,你可以調用scrollEventHandler中的解除綁定函數。它是如此簡單:

function unbindScrollEventHandler() { 
    $(document).unbind('scroll', scrollEventHandler); 
}