Javascript 选择与视口上边缘接触的元素的有效方法

Javascript 选择与视口上边缘接触的元素的有效方法,javascript,jquery,css,dom,Javascript,Jquery,Css,Dom,在滚动页面时,选择与浏览器窗口视口上边缘接触的元素的计算效率如何 请参阅所附图片。选择绿色元素是因为它们接触顶部边缘 更新 我将如何使用它的一个示例是淡出屏幕的元素。页面上可能有数百个。想象一下像Pinterest这样的页面。以scroll事件的速率计算成百上千个元素的偏移量和scrollTop,即使被限制,仍然感觉效率很低。我认为最好的方法是,您可以通过某个类标记要确定命中测试的元素,比如“命中测试可见”之类的。然后,对于这些元素,在滚动事件中,您应该能够找到它们相对于文档的偏移量-请参阅,

在滚动页面时,选择与浏览器窗口视口上边缘接触的元素的计算效率如何

请参阅所附图片。选择绿色元素是因为它们接触顶部边缘

更新


我将如何使用它的一个示例是淡出屏幕的元素。页面上可能有数百个。想象一下像Pinterest这样的页面。以scroll事件的速率计算成百上千个元素的偏移量和scrollTop,即使被限制,仍然感觉效率很低。

我认为最好的方法是,您可以通过某个类标记要确定命中测试的元素,比如“命中测试可见”之类的。然后,对于这些元素,在滚动事件中,您应该能够找到它们相对于文档的偏移量-请参阅,然后根据滚动值,如果偏移量小于滚动量,并且偏移量+元素高度大于滚动偏移量,则元素应该“接触”上边缘

这就是我想到的。我认为可以通过缓存scrollTop值来改进它,但这非常好。我已经包括了缓存boxtops的框架,但没有包括实现代码。我还只实现了向下滚动以隐藏div。我把它们放在upscroll上作为练习给你

当窗口滚动时,我们得到最后一个隐藏的div。我们知道在这个div之前的所有内容都已经隐藏。然后使用“下一个元素离开屏幕时”隐藏它。一个div没有离开屏幕,我们就中止。从而节省了遍历整个列表的时间

//跟踪用户是否向上或向下滚动
var prevScrollTop=$(document.scrollTop();
$(文档)。滚动(函数(){
var currentScrollTop=$(this.scrollTop();
如果(currentScrollTop>prevScrollTop){
//向下
var lasthiddenbox=$('.fadeboxhidden:last');
var nextbox=(lasthiddenbox.length>0)?lasthiddenbox.next('.fadebox'):$('.fadebox:first');
while(nextbox.length){
console.log('box:'+nextbox.offset().top+'scroll:'+currentScrollTop);
if(nextbox.offset().top
要知道哪一种方法最为理想,您可以采取几种方法:您的脚本是否知道要检测的所有元素的标识(即,它是固定的元素)?我知道这是一个老问题,但是为什么不在屏幕顶部安装一个css元素,它是一个从背景色到0%不透明度的渐变,z索引为99999或其他什么?不需要加载任何额外的js或任何东西。只是一个想法。因为它可以阻止在淡入淡出的区域中的点击,例如,我曾经用内框阴影尝试过这种方法。此外,并非所有浏览器都支持渐变背景(2011年也是如此)。如何扭转这种情况?。。我是说当你向上滚动的时候。
//track whether user has scrolled up or down
var prevScrollTop = $(document).scrollTop();

$(document).scroll(function() {
    var currentScrollTop = $(this).scrollTop();
    if (currentScrollTop > prevScrollTop) {
        //down
        var lasthiddenbox = $('.fadeboxhidden:last');
        var nextbox = (lasthiddenbox.length > 0) ? lasthiddenbox.next('.fadebox') : $('.fadebox:first');
        while (nextbox.length) {
            console.log('box: ' + nextbox.offset().top + ' scroll: ' + currentScrollTop);
            if (nextbox.offset().top < currentScrollTop) {
                nextbox.animate({ opacity: 0 }, 3000).addClass('fadeboxhidden');
            }
            else { return; } 
            nextbox = nextbox.next('.fadebox:first');
        }        
    } else {
        //up          
    }
    prevScrollTop = currentScrollTop ;
});

//create an object to hold a list of box top locations
var boxtops = new Object;


//gather all boxes and store their top location
$('.fadebox').each( function(index) {    
    //you may want to dynamically generate div ids here based on index. I didn't do this
    //because i was already using the id for positioning.
    var divid = $(this).prop('id');
    boxtops[divid] = $(this).offset().top;
    //console.log(boxtops[divid]);    
});