jQuery 2.1 |首先突出显示 <li> 在可滚动 <ol> 视口中完全可见

jQuery 2.1 | Highlight first <li> completely visible in scrollable <ol> viewport

我正在努力调整 this code from Whosebug 以满足我的特定需求。我需要通过 addClass 突出显示在滚动 <ol> 视口中完全可见的第一个 <li>,无论 <li> 的长度如何。我将代码的 $(window) 滚动部分替换为可滚动的 <ol>,它几乎可以完成工作,但在超过 <li> 长度后会导致偏移问题,因为 <li> 较小身高比 parent <ol> 身高 :

function testInView($el){
    var wTop = $('#OL').scrollTop() / 6; // Updated
    var wBot = wTop + $('#OL').height();
    var eTop = $el.offset().top;
    var eBot = eTop + $el.height();
    return ((eBot <= wBot) && (eTop >= wTop));
}
function setInView(){
    $("li").each(function(){
        var $zis = $(this);
        $zis.removeClass("inview");
        if(testInView($zis)){
           $zis.addClass("inview");
        }
    });
$('#OL').find('.inview:first').next().next().addClass(".higlight"); // Updated
}

$('#OL').scroll(function(){
    setInView();
});

我的 <ol> 在滚动时使六个 <li> 可见,每个高度为 80px,因此我的 <ol> 的高度为 480px。无论 <li> 的长度如何,如何编辑以上代码以使用这些高度,或者更好的是,可以编写代码以动态适应任何 <li> and/or <ol> 高度?

更新 1

我修改了上面的代码(见评论):

var wTop = $('#OL').scrollTop() / 6; // Added devide by 6

...

$('#OL').find('.inview:first').next().next().addClass(".higlight");
// Added two next()

以上编辑能够以更稳定的方式突出显示 <li> 目标,但是,随着 <li> 长度的增长,.highlight 会针对 bottom-most <li> 并且当 <li> 长度超过 38 时根本不适用。编辑更像是 hack 而不是可靠的解决方案,有关于更简洁高效代码的提示吗?

更新 2 - 最终版本

这个 Whosebug link 提供了我修改的“更干净高效的代码”,用作我上述问题的答案基础:

function setInView(){

var scroll = $('ol:visible').scrollTop() / 1000; // See Note below
var elements = $('ol:visible').find('li');
var el;

   for (var i=0; i<elements.length; i++) {
    elements.css('border-color',''); // Erase color with css
        el = $(elements[i]);
        if (el.offset().top >= scroll && el.is(':visible')){
            // "el" is the first visible element here!
            // Do something fancy with it
            el.next().next().css('border-color','#F00');
            // Quit the loop
            break;
        }
    }
}

$('ol').scroll(function(){
setInView();
});

注意<ol> 可见性选择器确保此函数仅针对可见的可滚动有序列表。除以 1000+ 可确保 <li> 长度为 600+ 的列表将被函数正确定位。我使用了 css 颜色交换,因为它们比我的应用程序的 类 处理起来更快。