检测窗口中呈现的div,以实现类似Google-Reader的自动标记读取?

在“扩展”视图中使用Google阅读器和浏览RSS条目时,一旦在屏幕上显示div的某个百分比,条目将自动标记为“已读”(在以下情况下难以分辨出必须显示的百分比)谷歌读者)。 因此,当我逐行向下滚动时,javascript代码可以确定a)条目在可见窗口中呈现并且b)某个量是可见的,并且当满足这些条件时,状态被切换为读取。

有谁知道该function是如何实现的? 具体来说,这里有没有人知道如何判断div是否已滚动查看div中可见多少?

顺便说一下,我正在使用jQuery,所以如果有人有任何jQuery特定的例子,他们将非常感激。

真正的诀窍是跟踪滚动条在包含项目的元素中的位置。 以下是我曾经做过的一些代码: http : //pastebin.com/f4a329cd9

您可以在滚动时看到它更改焦点。 您只需要为处理每个焦点更改的函数添加更多处理程序代码。 它可以在两个方向上滚动,也可以通过在滚动条上单击右键来实现,简单的鼠标跟踪不会给你(尽管在这种情况下,由于示例元素的大小都相同,文本相同,因此很难说它确实滚动了)。 另一个问题是当容器达到最低点时该怎么办。 我现在的解决方案只适用于FF。 如果你想在IE中看起来不错,你必须使用一个混合到背景中的虚拟元素,就像我在代码中注释掉的那样。

我刚刚遇到这个因为我需要同样的东西,它看起来非常有用:

http://www.appelsiini.net/projects/viewport

根据我的经验,如果我已经将鼠标hover或点击,那么读者只会将某些内容标记为已阅读。 假设滚动时鼠标滑过div(当我滚动时,我倾向于将鼠标放在屏幕的右边缘),这可能解释了当显示某个%时它只被标记为关闭的外观。

不过,我可能(而且可能是)错了。 我只知道只是在阅读器中滚动我的项目的行为并没有标记它们。 我必须确保鼠标在滚动时将鼠标移到它们上面。

dom和javascript允许您计算与其父元素的元素偏移量。 要计算窗口的偏移量,您需要使用递归并爬到顶部窗口,并将其与窗口大小进行比较。 由于跨浏览器问题和iframe,它变得更加复杂。

据我所知,prototype提供了一个简单的viewportOffset方法,可以为您完成大部分工作。 您还可以检查getOffsetParentscrollTo的源代码。 我不知道jquery,但我希望它提供类似的方法。

我的猜测是谷歌阅读器中的脚本只是在超时运行,可能是每秒几次,或者可能是为了响应滚动事件。 在这两种情况下,我确信它是自适应的(基于用户滚动的速度等超时更改等),并且它足够智能而不是资源耗尽(即,不要只检查所有的div)文件)

为了计算一个元素是否可见,你可以创建这样一个函数(信用到期为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:

 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中调用unbind函数。 它很简单:

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

你可以试试这个,关键点是元素必须对内体更加可见并且满足可见比例(在这种情况下为0.85)。

 isRead(element) { let rect = element.getBoundingClientRect(); const visibleRatio = 0.85; let elementRatio = (window.innerHeight - Math.abs(rect.top))/rect.height; let isRead = (rect.top >= 0) && (elementRatio >= visibleRatio); return isRead; }