Javascript 检测窗口中呈现的div以实现类似googlereader的自动标记为read?
当使用Google Reader并在“扩展”视图中浏览RSS条目时,一旦屏幕上可以看到某个百分比的div,条目将自动标记为“已读”(很难判断Google Reader中必须显示的百分比)。因此,当我逐行向下滚动时,javascript代码可以确定a)条目在可见窗口中呈现,b)一定量是可见的,当这些条件满足时,状态切换为读取 有人知道该功能是如何实现的吗?具体来说,这里有人知道如何判断一个div是否已滚动到视图中,以及该div有多少是可见的吗Javascript 检测窗口中呈现的div以实现类似googlereader的自动标记为read?,javascript,jquery,scroll,Javascript,Jquery,Scroll,当使用Google Reader并在“扩展”视图中浏览RSS条目时,一旦屏幕上可以看到某个百分比的div,条目将自动标记为“已读”(很难判断Google Reader中必须显示的百分比)。因此,当我逐行向下滚动时,javascript代码可以确定a)条目在可见窗口中呈现,b)一定量是可见的,当这些条件满足时,状态切换为读取 有人知道该功能是如何实现的吗?具体来说,这里有人知道如何判断一个div是否已滚动到视图中,以及该div有多少是可见的吗 顺便说一句,我正在使用jQuery,所以如果有人有任何
顺便说一句,我正在使用jQuery,所以如果有人有任何特定于jQuery的示例,我将不胜感激。根据我的经验,读者只有在我鼠标移动或单击某个内容时才会将其标记为已读。假设滚动时鼠标位于div上方(滚动时,我倾向于将鼠标放在屏幕的右边缘),这可能解释了为什么只有在显示某个百分比时,鼠标才会被标记
不过,我可能(也可能是)错了。我只知道在reader中滚动浏览我的项目并不会将它们标记出来。我必须确保鼠标在滚动时滑过它们。dom和javascript允许您计算元素相对于其父元素的偏移量。要计算与窗口的偏移量,您需要使用递归并爬升到顶部窗口,并将其与窗口的大小进行比较。由于跨浏览器问题和iFrame,它变得更加复杂 据我所知,prototype提供了一个简单的
viewportOffset
方法,可以为您完成大部分工作。您还可以检查getOffsetParent
和scrollTo
的源代码。我不知道jquery,但我希望它能提供类似的方法
我猜google reader中的脚本只是在超时时运行,可能每秒运行几次,或者响应滚动事件。在这两种情况下,我确信它是自适应的(超时根据用户滚动的速度等而改变),并且它足够聪明,不会占用资源(即,不要只检查文档中的所有div)真正的技巧是跟踪滚动条在包含项目的元素中的位置。这里有一些我曾经编写的代码:
你可以看到,当你滚动它改变焦点。您只需要向处理每个焦点更改的函数添加更多处理程序代码。它可以双向滚动,也可以右键单击滚动条,这是简单的鼠标跟踪所不能提供的(尽管在本例中,由于示例元素大小相同,文本相同,很难判断它是否确实滚动)。另一个问题是当容器触底时该怎么做。我现在的解决方案只适用于FF。如果你想让它在IE中看起来漂亮,你必须使用一个虚拟元素,它融入背景中,就像我在代码中注释掉的一样。我刚刚遇到这个问题,因为我需要同样的东西,它看起来非常有用:
为了计算元素是否可见,您可以创建这样一个函数(此处为积分): 您可以通过创建一个滚动监听器将其结合在一起(jQuery使这变得非常简单): 值得注意的是,如果您想解除滚动侦听器的绑定,比如说如果所有文章都已阅读并且不再需要收听滚动,那么可以在scrollEventHandler中调用unbind函数。这很简单:
function unbindScrollEventHandler() {
$(document).unbind('scroll', scrollEventHandler);
}
您可以试试这个,关键点是元素必须对内部实体更可见,并且满足可见比率(在本例中为0.85)
这是一个有趣的假设,所以这次我非常小心地避免涉及任何内容。我从“向下滚动”按钮开始,然后在窗口的外部向下滚动,并转到允许我在展开/列表视图之间切换的区域,条目被标记为已读。
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;
}
isScrolledIntoView(document.getElementById('targetDiv');
//or
isRead(document.getElementById('targetDiv');
function setScrollListener() {
var scrollEventHandler = function() {
if (isRead(document.getElementById('article'))) {
// set article to 'read'
}
}
// on scroll, fire the event handler
$(document).scroll(scrollEventHandler);
}
function unbindScrollEventHandler() {
$(document).unbind('scroll', scrollEventHandler);
}
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;
}